Source: https://www.jianshu.com/p/de0b74f58f50
pcntl
Is an operating system can use the fork
system call in PHP multi-threaded process control expansion, when using fork
code system calls will be parallel. pcntl
CLI mode only applies to the use of the Linux platform.
PHP official did not provide multi-threaded extensions, in pecl
there is a pthread
extension provides features multi-threaded, this version is only available in a thread-safe version.
Create a child processpcntl_fork
int pcntl_fork(void)
When pcntl_fork
will create a child process under the current process when the function is executed, the child and parent processes in the PID and PPID will be different.
The child will copy the parent process of all data, code, status and other information. When pcntl_fork
the child process is created successfully, the child will copy the code and data of the parent process. When the parent and child processes share the same code and data. The child process will replicate the state of the parent process.
When you use pcntl_fork
create a child process, if successful, will be in the parent process will return 0, in the child will return to its process number PID
. If you create failed to return -1
.
Use pcntl_fork
the process of creating just a branch node, the equivalent of a mark, after the completion of the parent process child process will continue from the mark, which means that pcntl_fork
each will be executed twice after code parent and child processes, and the two processes obtained during the execution of the return value is different, so it can be separated from the parent and child to execute different code.
In the Linux environment can use ps
command to see the process
<?php
$pid = pcntl_fork(); if($pid > 0){ //父进程 exit(0); }elseif($pid == 0){ //子进程 exit(0); }
The same effect multi-process and multi-threaded, the main difference lies in
- Multiple threads within the same process can be shared between threads and memory variables to communicate between threads.
- The process is more lightweight than threads, processes consume more system resources than threads.
Multithreading problems are mainly
- There is a thread to read and write variables need to lock synchronization problems
- Performance issues lock granularity over the General Assembly, will lead to only one thread is running, other threads are waiting for a lock, could not be achieved in parallel.
- When using multiple locks logic complexity, once a lock is not released properly thread deadlock may occur.
- A thread fatal error will cause the entire process to crash
Relatively more stable multi-process, interprocess communication can be used IPC
to achieve data sharing technology. Multi-way communication process include
- Shared memory
when memory and shared between threads to read and write the same variable, we need to lock, there is also a synchronization, deadlocks, and other issues. - Message Queuing
message queues are queues of a plurality of sub-processes preemption mode, better performance. - Pipe, UnixSock, TCP, UDP
may be usedread/write
to pass data, TCP / UDP socket used for communication, sub-process may be distributed to run.
The use of fork
system calls can be achieved concurrent TCP server, the main process accept
client connections. When there is a direct connection when the arrival of a new fork
a child process, the child process cycle recv/send
to process data. This mode is useful in the case of small amount of a request, such as FTP servers.
Most Linux programs in the past when using this mode, simple and efficient, less code. When there are hundreds of cases of concurrent performed well, but in the case of large concurrent consumption will be too large.
For example: each child process can create a file with the corresponding parent process can create a file of their own.
<?php
$socket = socket_create(AF_INET, SOCK_STREAM, 0); if($socket < 0){ $errmsg = socket_strerror($socket); echo "failed to create socket: {$errmsg}".PHP_EOL; exit; } $host = "0.0.0.0"; $port = 9601; $ret = socket_bind($socket, $host, $port); if($ret < 0){ echo "failed to bind socket: {$ret}".PHP_EOL; exit; } $ret = socket_listen($socket, 0); if($ret < 0){ $errmsg = socket_strerror($ret); echo "failed to listen: {$errmsg}".PHP_EOL; exit; } while(pcntl_fork() == 0){ $connection = @socket_accept($socket); if(pcntl_fork() == 0){ $recv = socket_read($connection ,8192); $data = "serverr: {$recv}"; socket_write($connection ,$data); socket_close($connection); exit(0); }else{ socket_close($connection); } }