What is a process? A process is an executing program; a process is an instance of a program being executed on a computer; a process is an entity that can be assigned to and executed by a processor. A process generally includes an instruction set and a system resource set. The instruction set here refers to the program code, and the system resource set here refers to I/O, CPU, memory, etc. To sum up, we can also understand that a process is a running activity of a program with certain independent functions on a certain data collection. A process is an independent unit for resource allocation and scheduling in the system.
When a process is executed, the process can be uniquely represented, consisting of the following elements:
Process descriptor: the unique identifier of the process, used to Other processes are distinguished. It is called process ID in Linux and is generated during the system call fork. However, what we return through getpid is not its pid field, but its thread group number tgid.
Process status: The states we often refer to as suspend, running, etc., represent the current state.
Priority: related to execution scheduling between processes, relative to other processes.
Program counter: The address of the next instruction to be executed in the program. This address is the memory address in the kernel or user memory space.
Memory pointers: including pointers to program code and process-related data, as well as pointers to shared memory blocks with other processes.
Context data: Data in the processor's registers when the process is executed.
I/O status information: including explicit I/O requests, I/O devices assigned to processes, etc.
Accounting Information: It may include the total processor time, the total number of clocks used, time limits, etc.
The above elements will be placed in a data structure called the process control block. The process control block is a structure that enables the operating system to support multiple processes and provide multiprocessing. When the operating system switches processes, it performs two steps: one is to interrupt the process in the current processor, and the other is to execute the next process. Regardless of interrupt or execution, the program counter, context data, and process state in the process control block will change. When the process is interrupted, the operating system will save the program counter and processor register (corresponding to the context data in the process control block) to the corresponding location in the process control block. The process state will also change, and it may enter a blocking state, or it may enter a blocking state. Enter the ready state. When executing the next process, the operating system sets the next process to the running state according to rules and loads the program context data and program counter of the process to be executed.
A process has two characteristic parts: resource ownership and scheduling execution. Resource ownership means that the process includes the memory space, I/O and other resources required for the process to run. Scheduling execution refers to the execution path in the middle of the process execution, or the instruction execution flow of the program. These two feature parts can be separated. After separation, the one with data ownership is usually called a process, and the one with the dispatchable part of the execution code is called a thread or lightweight process.
Threads have the meaning of "execution clues", and the process is defined as the resource owner in a multi-threaded environment, and it will still store the process control block of the process. The structure of threads is different from that of processes. Each thread includes:
Thread status: The current status of the thread.
An execution stack
Private data area: Static storage space for local variables of each thread
Register Set: Stores some state of the processor
Each process has a process control block and user address space, and each thread has a Independent stacks and independent control blocks have their own independent execution context. Its structure is shown in Figure 8.1.
Figure 8.1 Process model diagram
Threads are somewhat different from processes during execution. Each independent thread has an entry point for program execution, a sequential execution sequence, and an exit point for the program. However, threads cannot execute independently and must exist in the process, and the process provides execution control of multiple threads. From a logical point of view, the meaning of multi-threading is that in a process, multiple execution parts can be executed at the same time. At this time, the process itself is not the basic running unit, but the container of threads.
The advantage of threads over processes is that they are faster. Whether it is creating a new thread or terminating a thread; whether it is switching between threads or sharing data or communication between threads, its speed is faster than that of a process. Big advantage.
Concurrency, also known as co-concurrency, refers to the ability to handle multiple simultaneous activities. Concurrent events do not necessarily have to be the same happens all the time. For example, modern computer systems can load multiple programs into memory in the form of processes at the same time, and use time-division multiplexing of the processor to present the feeling of running simultaneously on one processor.
Parallel refers to two concurrent events that occur at the same time, which has the meaning of concurrency, but concurrency is not necessarily parallel.
The difference between concurrency and parallelism is that a processor processes multiple tasks at the same time and multiple processors or multi-core processors process multiple different tasks at the same time. The former is logical simultaneous, while the latter is physical simultaneity.
Since there are two models, which one does PHP use? The answer is that they all are supported, which means that PHP supports the multi-threaded model. In multi-threaded situations, the problems of resource sharing and isolation usually need to be solved. PHP itself is thread-safe.
The specific model depends on which SAPI is used. For example, in Apache, then the multi-thread model or the multi-process model may be used. And php-fpm uses the multi-process model.
The currently recommended way is to use the php-fpm model, because this model has many advantages for PHP:
Memory release is simple, When using the multi-process model, the process can easily release memory by exiting. Since PHP has many extensions, memory leaks may occur if you are not careful. FPM solves the problem simply by exiting the process.
Strong disaster recovery capability. With the same problem, extensions or PHP may cause segfaults. If it is a single-process multi-thread model, then the entire PHP will hang. This will affect the service. If there are multiple processes, the death of a certain process will not affect the overall service.
Multiple processes have the advantages of multiple processes, and multi-threading also has the advantages of multi-threading. For example, HHVM chooses the multi-threading model. The biggest benefit of the multi-threading model is the convenience of information sharing and communication, because pointers can be used directly in the same process space.
For example, the opcode cache tool. In PHP, apc, opcache, etc. use shared memory to share opcode. In HHVM, there is no need to use shared memory. Another problem with shared memory is that the storage is complicated. Data structures are inconvenient because of pointer issues. Data structures in C/C++ can be shared in multi-threaded situations. This is also helpful for improving efficiency.
There is another obvious model difference between multi-process and multi-thread: the logic when processing requests.
In the case of multiple processes, it is difficult to transfer the FD connection across processes. So many processes usually use listen()
in the parent process, and then accept()
in each child process to achieve load balancing. There may be a herd problem under such a model.
Under the multi-threading model, an independent thread can be used to accept the request and then dispatch it to each worker thread.
Related recommendations:
Detailed explanation of single-threaded JS execution issues
PHP’s support and use of multi-threaded programming
A case of implementing PHP multi-threading class
The above is the detailed content of Detailed explanation of PHP thread processes and concurrent instances. For more information, please follow other related articles on the PHP Chinese website!