[Reprint] The difference between processes and threads (understood from the operating system level)

1. What is a process? Why have a process?

A process has a rather concise explanation: a process is an abstraction of a program running on the operating system.

This concept is indeed quite abstract, but if you think about it carefully, it is quite precise.

When we usually use computers, we do many things at the same time, such as watching movies, chatting on WeChat, and opening the browser Baidu to search. Behind so many things we do are running software programs; these If the software wants to run, it must first have its own program code on the disk, and then load the code into the memory. The CPU will execute the code. During operation, a lot of data will be generated that needs to be stored, and it may also need to be combined with the network card, graphics card, and keyboard. When external devices interact, this actually involves the use of computer resources by programs. With so many programs, of course we need to find ways to manage the use of program resources. And if there is only one CPU, then the operating system needs to schedule the CPU to be allocated to various programs, so that users can feel that these programs are running at the same time without affecting the user experience.

Of course, the operating system will encapsulate each running program into an independent entity, allocate the resources required by each, and then switch execution according to the scheduling algorithm . This abstract program entity is the process.

Therefore, many official explanations of processes will mention: A process is a basic unit for resource allocation and scheduling by the operating system .

2. What is a thread? Why have threads?

In early operating systems, there was no concept of threads. A process is the smallest unit that has resources and can run independently. It is also the smallest unit of program execution. Task scheduling adopts the preemptive scheduling method of time slice rotation , and the process is the smallest unit of task scheduling. Each process has its own independent memory space, so that the memory addresses of each process are isolated from each other.

Later, with the development of the computer industry, the functional design of programs became more and more complex. Multiple activities occurred simultaneously in our applications, some of which would be blocked over time, such as network requests, reading and writing files ( That is, IO operations), we naturally wonder whether these applications can be decomposed into finer granularity, whether multiple sequential execution entities can be run in parallel, and these fine-grained execution entities can share the address space of the process, that is, they can Sharing program code, data, memory space, etc. makes the programming model simpler.

In fact, many technological developments in the computer world are simulating the real world. For example, we regard a process as a project. When the project tasks become complex, we naturally think about whether we can divide the project into task modules according to business, product, work direction, etc., and assign them to different people to complete in parallel, and then according to some kind of method to organize their respective task results and finally complete the project.

Another important reason for the need for multi-threading is that each process has an independent code and data space (program context), and switching between programs will have a large overhead; threads can be regarded as lightweight processes, and the same Class threads share code and data space. Each thread has its own independent running stack and program counter, and the overhead of switching between threads is small. Therefore, the creation, destruction, and scheduling performance of threads are far better than those of processes .

After the introduction of the multi-threading model, the division of labor between processes and threads during program execution is quite clear. The process is responsible for allocating and managing system resources, and the thread is responsible for CPU scheduling operations , and is also the smallest unit of CPU switching time slice. For any process, even if we do not actively create a thread, the process has a main thread by default.

3. How are they different in the way they are implemented in the Linux kernel?

task_struct In Linux, whether it is a process or a thread, in the kernel, we call it a task (Task), which is managed by a unified structure. This data structure is very task_structcomplex and includes various information in the process management life cycle.
Insert image description here
The first process is created when the Linux operating system kernel is initialized, that is 0号创始进程. Then process No. 1 (user process ancestor: /usr/lib/systemd/systemd) and process No. 2 (kernel process ancestor: [kthreadd]) will be initialized, and all subsequent process threads will be forked based on them.

#ps -ef
UID         PID   PPID  C STIME TTY          TIME CMD
root          1      0  0  2022 ?        05:05:39 /usr/lib/systemd/systemd --switched-root --system --deserialize 22
root          2      0  0  2022 ?        00:00:07 [kthreadd]
root          3      2  0  2022 ?        00:00:00 [rcu_gp]
root          4      2  0  2022 ?        00:00:00 [rcu_par_gp]
root          6      2  0  2022 ?        00:00:00 [kworker/0:0H-ev]
root          8      2  0  2022 ?        00:00:00 [mm_percpu_wq]
root          9      2  0  2022 ?        00:00:00 [rcu_tasks_rude_]
root         10      2  0  2022 ?        00:00:00 [rcu_tasks_trace]
root         11      2  0  2022 ?        00:01:43 [ksoftirqd/0]

Insert image description here
We generally forkcreate new processes through system calls. The fork system call contains two important events. One is to copy and initialize the task_struct structure, and the other is to try to wake up the newly created child process.

We say that whether it is a process or a thread, they are all tasks in the kernel. Aren't they managed the same? How to tell the difference? In fact, threading is not a mechanism completely implemented by the kernel. It is completed by the cooperation of kernel mode and user mode .
https://www.ixigua.com/6972128479705825829
When creating a process, the system call called is fork, which will copy the five major structures files_struct, fs_struct, sighand_struct, signal_struct, from then on. From then on, the parent process and the child process each use their own data structures. mm_structWhen creating a thread, the system call clone is called. The five major structures are just the reference count plus one, which is the data structure of the thread sharing process .
Insert image description here

4. Summarize the difference between processes and threads?

Function : Process is the basic unit of operating system resource allocation, and thread is the basic unit of task scheduling and execution.

Overhead : Each process has an independent memory space to store code and data segments, etc. Switching between programs will have a large overhead; threads can be regarded as lightweight processes, sharing memory space, and each thread has It has its own independent running stack and program counter, and the overhead of switching between threads is small.

Running environment : In the operating system, multiple processes can be run at the same time; in the same process (program), multiple threads are executed at the same time (through CPU scheduling, only one thread is executed in each time slice)

Creation process : When creating a new process, all five data structures of the parent process will be copied to form its own new memory space data. When creating a new thread, the five data structures of the process will be referenced. However, Threads will have their own private data and stack space.

In fact, processes and threads are encapsulated in the task_struct structure from the perspective of the CPU. They can execute different tasks. In addition, from the perspective of the CPU, they follow the corresponding scheduling strategy and context resource switching definitions when executing these tasks, including register address switching, kernel Stack switch. So for the CPU, there is no difference between processes and threads.

Attachment: What do we mean by context switching?

The operating system abstracts the concept of a process, allowing applications to focus on implementing their own business logic. It shields applications from hardware details such as CPU scheduling and memory management, and can perform many tasks "simultaneously" on a limited CPU. . But while it brings convenience to users, it also introduces some additional overhead.

In the operating system, due to the time slice scheduling policy of the CPU, switching from one process to another requires saving the state of the current process and restoring the state of the other process: the currently running task changes to the ready (or suspended, deleted) state, Another selected ready task becomes the current task. Context switching includes saving the running environment of the current task and restoring the running environment of the task to be run.

During the context switch process, the CPU will stop processing the currently running program and save the specific location of the current program to continue running later. From this perspective, context switching is a bit like us reading several books at the same time. While switching books back and forth, we need to remember the current page number of each book.

Context switching may occur in three situations: interrupt handling, multitasking, and kernel/user mode switching .

In interrupt handling, other programs "interrupt" the currently running program. When the CPU receives an interrupt request, it will perform a context switch between the running program and the program that initiated the interrupt request.

In multitasking, the CPU switches back and forth between different programs. Each program has a corresponding processing time slice, and the CPU performs context switching in the interval between the two time slices.

Kernel/user mode switching in Linux will also cause context switching. When making a system call, the original user mode instruction location in the CPU register needs to be saved first. Next, in order to execute kernel-mode code, the CPU registers need to be updated with the new locations of the kernel-mode instructions. Finally, it jumps to the kernel state to run the kernel task. After the system call ends, the CPU registers need to restore the originally saved user state, and then switch to the user space to continue running the process. Therefore, during a system call, two CPU context switches actually occur.

CPU context switching is one of the core functions to ensure the normal operation of the Linux system. Generally, we do not need to pay special attention to it.

However, excessive context switching will consume CPU time in saving and restoring data such as registers, kernel stacks, and virtual memory, thereby shortening the actual running time of the process and causing a significant decline in the overall performance of the system.

Original link: https://blog.csdn.net/qq_40989769/article/details/129047723

Guess you like

Origin blog.csdn.net/yuelai_217/article/details/130198483