You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
**Multithreading** is a concept that enable us to use multiple thread to execute tasks.
15
+
**Multithreading** is a concept that enable us to use multiple thread to execute tasks. See [concurrency](/computer-and-programming-fundamentals/concurrency) for an introduction to concurrency.
16
16
17
17
### Thread
18
18
19
-
Thread is a unit of execution in CPU, it can execute a set of instruction, basically it is a "worker" in a CPU. Thread exist within a [process](/operating-system/process-management#process--thread) and has its own data including thread ID, program counter, a register set, and a stack.
19
+
Thread is a unit of execution in CPU, it can execute a set of instruction. Basically, it is a "worker" in a CPU. Thread exist within a [process](/operating-system/process-management#process--thread) and has its own data including thread ID, program counter, a register set, and a stack.
20
20
21
-
In multithreading, instead of just one thread or one worker in a process, multiple thread is utilized. The benefit is we are not limited to complete a single task at a time, for example, a mobile app can fetch data from remote server while also loading data from local storage. If possible, we can also divide a computationally intensive task into smaller, parallelizable subtasks, and use multiple threads to speeds up the overall execution time.
21
+
In multithreading, instead of just one thread or one worker in a process, multiple thread is utilized. The benefit is we are not limited to complete a single task at a time. For example, a mobile app can fetch data from remote server while also loading data from local storage. If possible, we can also divide a computationally intensive task into smaller, parallelizable subtasks, and use multiple threads to speeds up the overall execution time (achieving parallelism).
22
22
23
23
A thread can also be **blocked**, which means the thread is unable to make progress or continue its execution because it is waiting for a certain event such as I/O results or condition to occur. Blocked thread can be inefficient, as it is unable to perform any useful work.
The image above shows the illustration of multithreading. Each thread holds different data, but they share the same memory space and resources of the parent process. In contrast, multiprocessing is when we utilize a processor that has several cores. Each core would have their own data and thread that will execute simultaneously.
29
29
30
-
Utilizing multiple threads is typically more efficient than making multiple process that execute the same tasks. Threads have a smaller memory footprint, require less time for [context switching](/operating-system/process-management#context-switch), and have lower scheduling overhead. Also, separate process means [IPC](/operating-system/inter-process-communication) is required to communicate between processes, whereas thread shares the same memory within a process, thus communication will be easier.
30
+
Utilizing multiple threads is typically more efficient than making multiple process that execute the same tasks ([multiprocessing](/computer-and-programming-fundamentals/concurrency#multiprocessing)). Threads have a smaller memory footprint, require less time for [context switching](/operating-system/process-management#context-switch), and have lower scheduling overhead. Also, separate process means [IPC](/operating-system/inter-process-communication) is required to communicate between processes, whereas thread shares the same memory within a process, thus communication will be easier.
31
31
32
32
### Multithreading Model
33
33
34
34
#### User & Kernel Thread
35
35
36
36
There are two types of thread, **user thread** and **kernel thread**.
37
37
38
-
User threads, also known as **green threads**, are implemented and managed by a thread library or runtime system at the user level, without direct involvement of the operating system kernel. The creation, scheduling, and synchronization of user threads are handled entirely in the user space (memory space where user applications run).
38
+
User threads, also known as **green threads**, are implemented and managed by a thread library or runtime system at the user level, without direct involvement of the operating system kernel. The creation, scheduling, utilization, and synchronization of user threads are handled entirely in the user space (memory space where user applications run). They may not be able to access the memory used by kernel.
39
39
40
40
On the other hand, kernel threads, which is also known as **native threads**, are managed directly by the operating system kernel. Each kernel thread is represented as a separate entity within the operating system and has its own program counter, stack, and thread control block.
41
41
@@ -45,7 +45,9 @@ Kernel threads are heavyweight, they require system calls and interaction with t
45
45
46
46
#### Relationship Model
47
47
48
-
-**Many-to-One** : This model involves mapping multiple user-level threads to a single kernel-level thread. The thread management and scheduling are performed by a thread library or runtime system at the user level, and the operating system sees only a single thread. This model has efficient management, but may not take full advantage of multiprocessor systems as the execution of multiple threads is handled by a single kernel-level thread.
48
+
Relationship model between user and kernel thread describe how they are associated with each other.
49
+
50
+
-**Many-to-One** : This model involves mapping multiple user-level threads to a single kernel-level thread. The thread management and scheduling are performed by a thread library or runtime system at the user level. From the programming language, we can see and use multiple thread, but under the hood the operating system sees only a single thread. This model has efficient management, but may not take full advantage of multiprocessor systems as the execution of multiple threads is handled by a single kernel-level thread.
49
51
-**One-to-One** : In this model, each user-level thread is mapped to a separate kernel-level thread by the operating system. This model provides more concurrency and true parallelism to the kernel-level. However, the overhead of creating and managing kernel-level threads can be higher compared to other models.
50
52
-**Many-to-Many** : This model combines the aspect of many-to-one and one-to-one. Many-to-many model consist of many kernel threads and smaller or equal number of user thread. The operating system can create multiple kernel-level threads, while the thread library manages and schedules the user-level threads across the available kernel-level threads.
51
53
@@ -58,7 +60,7 @@ Multithreading implementation depends on the programming language used. Threadin
58
60
59
61
#### Thread Creation & Termination
60
62
61
-
The thread library provided by programming languages have specific function or method to create and manage threads. For example, in Java, we can create a thread by extending the `Thread` class or implementing the `Runnable` interface and then invoking the `start()` method. In C++, you can use the `std::thread` class or the threading utilities provided by libraries like POSIX threads (`pthread_create()` function).
63
+
The thread library provided by programming languages have specific function or method to create and manage threads. For example, in Java, we can create a thread by implementing the `Thread` class or the `Runnable` interface and then invoking the `start()` method. In C++, you can use the `std::thread` class or the threading utilities provided by libraries like POSIX threads (`pthread_create()` function).
62
64
63
65
When creating thread, we can specify thread attributes such as stack size, thread priority, CPU affinity. After a thread is created, it is assigned a unique identifier called the thread ID.
64
66
@@ -69,6 +71,78 @@ Thread can be stopped explicitly using function like `stop()` in Java. Sometimes
69
71
70
72
It is important to note that thread termination should be handled carefully. For example, a thread may have used some data structure, but when it is not freed before the termination, this can cause [memory leak](/computer-security/other-attack-and-exploit#memory-leak).
71
73
74
+
##### Example
75
+
76
+
One reason to implement the `Thread` class is to encapsulate application logic that is intended to be run in separate thread. In a server app, it is expected that the server handle multiple request in parallel. Let's say server is trying to read and write an input.
For each client connection, we create a new thread through the `ClientHandlerThread` and start it to handle the connection.
145
+
72
146
#### Thread Execution & Scheduling
73
147
74
148
In Java, we can start the execution of a thread, by calling the `start()` method on the `Thread` object. The `start()` method internally calls the thread's `run()` method, which contains the code that will be executed by the thread. The JVM manages the execution of threads and ensures that the `run()` method is executed concurrently with other threads.
Multiple threads exist within the same process, threads communicate using the [IPC mechanism](/operating-system/inter-process-communication). There are two method, the first method is **[shared memory](/operating-system/inter-process-communication#shared-memory)**, where each thread read and write data in the same region of memory. The other method is **[message passing](/operating-system/inter-process-communication#message-passing)**, where they send messages or signals to each other. One thread can send a message to another thread, which then receives and processes the message.
159
+
Multiple threads exist within the same process, external threads can communicate using the [IPC mechanism](/operating-system/inter-process-communication). There are two method, the first method is [shared memory](/operating-system/inter-process-communication#shared-memory), where each thread read and write data in the same region of memory. The other method is [message passing](/operating-system/inter-process-communication#message-passing), where they send messages or signals to each other. One thread can send a message to another thread, which then receives and processes the message.
160
+
161
+
:::note
162
+
Although they are for process communication, it may be used to communicate between thread if they are running in separate processes. If threads were to communicate between the same process, typically they would directly access and communicate with each other through shared variables or data structures.
163
+
:::
86
164
87
165
#### Thread Synchronization
88
166
@@ -96,7 +174,7 @@ These are fundamental tools used in multithreaded programming to synchronize.
96
174
97
175
###### Locks / Mutex
98
176
99
-
**Mutex (mutual exclusion)** is a synchronization primitive that ensure only one thread to access a shared resource. It works by having a lock, a thread that wants to access the resource must acquire the lock first. If the lock is already held by another thread, the requesting thread will be blocked until the lock is released. When the thread that access the resource has finished, then the lock will be released.
177
+
**Mutex (mutual exclusion)** is a synchronization primitive that ensure only one thread to access a shared resource. It works by having a lock, a thread that wants to access the resource must _acquire_ the lock first. If the lock is already held by another thread, the requesting thread will be blocked until the lock is _released_. If the thread that access the resource has finished, only then the lock will be released.
100
178
101
179
The mutex technique can be implemented in the software-level by memory synchronization instructions provided by the hardware architecture.
The same concept applies for shared memory, where there are several processes each with their own isolated virtual memory. When a process want to share memory, the OS will allocate some shared memory somewhere. After that, the process will attach to it, meaning the process will be given some range of address on their virtual address that it can use to access the shared data. Essentially, the OS maps the shared memory to the virtual memory owned by the process.
39
+
The same concept applies to shared memory, where multiple processes each have their own isolated virtual memory. When a process wants to share memory, the operating system allocates some shared memory. Then, the process attaches the shared memory to each process. This means that every process is given a range of addresses on their virtual address space that they can use to access the shared data.
@@ -53,16 +53,17 @@ Message passing can be synchronous or asynchronous. In the synchronous model, th
53
53
54
54
Some example of message passing :
55
55
56
-
-**Pipes** : Pipes are a form of [inter-process communication (IPC)](/operating-system/inter-process-communication) that allows the output of one process to be used as the input of another process. In a pipe, data flows in a unidirectional manner from the writer process to the reader process. Pipes can be either named or unnamed, with unnamed pipes typically used for communication between related processes (e.g., parent-child processes).
56
+
-**Pipes** : Pipes are a form of IPC that allows the output of one process to be used as the input of another process. In a pipe, data flows in a unidirectional manner from the writer process to the reader process. Pipes can be either named or unnamed, with the latter typically used for communication between related processes (e.g., parent-child processes).
57
57
58
-
-**Sockets** : Sockets are a communication endpoint that enables bidirectional communication between processes over a network. They can be used for IPC within the same machine (domain sockets) or across different machines (network sockets).
-**Sockets** : Sockets are a communication endpoint that enables bidirectional communication between processes over a network. They can be used for IPC within the same machine (domain sockets) or across different machines (network sockets).
60
62
-**[Message Queues](/backend-development/message-broker)** : Message queues is where processes exchange messages through a shared [queue](/data-structures-and-algorithms/queue) in the operating system. Each message has a specific format and is placed into the queue by the sending process. The receiving process can then retrieve messages from the queue in a first-in-first-out (FIFO) order.
61
-
62
63
-**Channels** : Channels is a higher-level concept for message passing. Channels typically provide a set of operations, such as sending and receiving messages, and may incorporate synchronization mechanisms like blocking or non-blocking operations. Channels can be implemented using various underlying mechanisms, including shared memory, pipes, or sockets.
0 commit comments