Threads and Multithreading in Operating System

Subject: Computer Science Fundamentals · Language: Operating System · Level: intermediate · 9 min read

Understand threads and multithreading with process vs thread, shared resources, thread benefits, user/kernel threads, and threading problems.

A thread is the smallest unit of execution inside a process. When a process runs, the CPU actually executes threads. A process can have one thread or many threads depending on how the program is designed. For beginners, it is useful to think of a process as a container and threads as workers inside that container. The process owns resources such as memory and files, while threads perform the actual execution work. Multithreading means using multiple threads inside the same process. This allows different parts of a program to run independently or appear to run at the same time.

Process vs Thread

A process is a running program with its own memory space and resources. A thread is a smaller execution unit inside a process. Multiple threads of the same process share many resources, but each thread also has its own execution state. A process is heavier than a thread. Creating a new process usually needs more memory and more OS work. Creating a thread is usually lighter because threads share the process memory and resources.

If one process crashes, it usually does not directly damage another process because processes are isolated. But if one thread inside a process causes a serious error, it can affect the whole process because threads share the same process environment.

What Threads Share

Threads of the same process share the code section, data section, heap memory, and open files. This sharing makes communication between threads easier because they can access common data inside the same process. For example, in a web browser process, one thread may handle user input, another may download data, and another may render page content. These threads can share process resources while doing different tasks. Sharing is useful, but it also creates risk. If two threads update the same data at the same time, the result may become incorrect. This is why synchronization is important in multithreaded programs.

What Each Thread Has Separately

Each thread has its own program counter, registers, and stack. The program counter tells which instruction the thread will execute next. Registers store temporary CPU values. The stack stores function calls and local variables for that thread. This separate execution state allows each thread to run independently. One thread may be inside one function while another thread is inside a different function of the same process.

Why Threads Are Needed

Threads are needed to improve responsiveness, resource sharing, and performance. A program with only one thread may become unresponsive if that thread waits for input-output. With multiple threads, one thread can wait while another continues working. For example, a text editor can use one thread for typing and user interface, another thread for auto-saving, and another thread for spell checking. If auto-save takes time, the user can still continue typing. Threads are also useful on multi-core processors. Different threads can run on different CPU cores at the same time, improving performance for suitable tasks.

Single-Threaded Process

A single-threaded process has only one thread of execution. It performs one sequence of instructions at a time. If that thread blocks, the whole process may wait. Single-threaded programs are simpler to write and debug because there is no shared-thread timing problem. However, they may not use modern multi-core CPUs effectively and may become less responsive during long tasks.

Multithreaded Process

A multithreaded process has more than one thread. Each thread can perform a separate task. Threads can run concurrently, and on multi-core systems they may run in parallel. Concurrency means tasks make progress during the same time period. Parallelism means tasks literally run at the same instant on different CPU cores. Multithreading can support both, depending on hardware and OS scheduling.

Benefits of Multithreading

The first benefit is responsiveness. A user interface can remain active while background work continues. This is important in browsers, editors, games, and mobile apps. The second benefit is resource sharing. Threads in the same process share memory and files, so communication is easier than communication between separate processes.

The third benefit is economy. Creating and switching threads is usually cheaper than creating and switching processes because threads are lighter. The fourth benefit is scalability. On multi-core systems, multiple threads can run on different cores, allowing the program to complete work faster if the task can be divided properly.

Problems with Multithreading

Multithreading also creates problems. The most important problem is race condition. A race condition happens when multiple threads access shared data at the same time and the final result depends on timing. Another problem is deadlock. Threads may wait for each other forever if locks are not used carefully. For example, one thread may hold lock A and wait for lock B, while another holds lock B and waits for lock A. Debugging multithreaded programs can be difficult because errors may not happen every time. A program may work correctly once and fail later depending on thread timing.

User-Level Threads

User-level threads are managed by a thread library in user space. The operating system kernel may not know about each individual user-level thread. The thread library handles creation, scheduling, and switching of these threads. User-level threads can be fast because switching between them may not require kernel involvement. However, if one user-level thread makes a blocking system call, the entire process may block depending on the implementation.

Kernel-Level Threads

Kernel-level threads are managed directly by the operating system kernel. The OS knows about each thread and can schedule them independently. Kernel-level threads are more powerful because if one thread blocks, the OS can schedule another thread of the same process. They can also run on multiple CPU cores. The disadvantage is that managing them may have more overhead than user-level threads.

Many-to-One, One-to-One, and Many-to-Many Models

In the many-to-one model, many user threads are mapped to one kernel thread. It is simple, but one blocking thread can block the entire process, and true parallelism is not possible. In the one-to-one model, each user thread maps to one kernel thread. This allows better concurrency and parallelism, but creating too many threads can increase overhead. In the many-to-many model, many user threads are mapped to a smaller or equal number of kernel threads. This model tries to balance flexibility and efficiency.

Thread Scheduling

Threads also need scheduling. The OS decides which thread should run on the CPU. If threads are kernel-level threads, the OS scheduler can schedule them directly. Thread scheduling affects responsiveness and performance. For example, a user interface thread should get CPU quickly so the application feels smooth. Background threads can often run with lower priority.

Thread Example in Daily Life

Consider a web browser. One thread may handle user clicks and scrolling. Another thread may download data from the internet. Another thread may render the webpage. Another thread may play audio or video. If the browser used only one thread, downloading a large file could freeze the entire browser interface. With multiple threads, the browser can continue responding while background tasks continue.

Summary

A thread is a lightweight execution unit inside a process. Threads of the same process share code, data, heap, and open files, but each thread has its own program counter, registers, and stack. Multithreading improves responsiveness, resource sharing, economy, and scalability. However, it also introduces problems such as race condition, deadlock, and difficult debugging. Understanding threads is important before studying synchronization and deadlock deeply.

Why Threads Are Lighter Than Processes

Threads are considered lighter than processes because threads of the same process share the same address space and resources. Creating a new process usually needs separate memory and more operating system work, while creating a thread can be faster. This does not mean threads are always simple. Since threads share data, they must be synchronized carefully. A mistake in one thread can affect other threads in the same process because they belong to the same program.

Threads in Real Applications

Many applications use threads to stay responsive. For example, one thread may handle the user interface while another thread downloads data or performs a background calculation. This prevents the whole application from freezing during long work. Servers also use threads to handle multiple clients. Instead of making every client wait for one request to finish, a server can process many requests concurrently using threads or similar concurrency models.

More Operating System Lessons

Browse all PrepCampus study materials