environment
The process in php is completed in the form of extension. Through these extensions, we can easily complete a series of actions of the process.
pcntl extension: the main process extension, which completes the process creation in the waiting operation.
posix extension: complete the general api of posix compatible machine, such as obtaining process id, killing process, etc.
sysvmsg extension: message queue for inter process communication in system v mode.
sysvsem extension: realize the semaphore of system v mode.
sysvshm extension: realize the shared memory of system v mode.
sockets extension: realize socket communication.
These extensions can only be used in linux/mac and are not supported in window s. Finally, php version is recommended to be 5.5 +.
Simple example
A simple PHP multi process example. In this example, a child process and a parent process. The subprocess outputs 5 times and exits the program.
echo "parent progress pid:{$parentPid}\n"; $childList = array(); $pid = pcntl_fork(); if ( $pid == -1) { // Creation failed exit("fork progress error!\n"); } else if ($pid == 0) { // Subprocess executor $pid = posix_getpid(); $repeatNum = 5; for ( $i = 1; $i <= $repeatNum; $i++) { echo "({$pid})child progress is running! {$i} \n"; $rand = rand(1,3); sleep($rand); } exit("({$pid})child progress end!\n"); } else { // Parent process executor $childList[$pid] = 1; } // Wait for the child process to end pcntl_wait($status); echo "({$parentPid})main progress end!";
Perfect, finally created a child process, a parent process. Is it over? No, the processes are independent of each other and have no intersection. The scope of use is seriously affected now. What to do? It's interprocess communication.
4, Interprocess communication (IPC)
Generally, the process communication methods in linux include: message queue, semaphore, shared memory, signal, pipeline and socket.
1. Message queue
A message queue is a queue stored in memory. The following code will create three producer subprocesses and two consumer subprocesses. The five processes will communicate through message queuing.
echo "parent progress pid:{$parentPid}\n";$childList = array(); // Create message queues and define message types (similar to libraries in a database) $id = ftok(__FILE__,'m'); $msgQueue = msg_get_queue($id); const MSG_TYPE = 1; // producer function producer(){ global $msgQueue; $pid = posix_getpid(); $repeatNum = 5; for ( $i = 1; $i <= $repeatNum; $i++) { $str = "({$pid})progress create! {$i}"; msg_send($msgQueue,MSG_TYPE,$str); $rand = rand(1,3); sleep($rand); } } // consumer function consumer(){ global $msgQueue; $pid = posix_getpid(); $repeatNum = 6; for ( $i = 1; $i <= $repeatNum; $i++) { $rel = msg_receive($msgQueue,MSG_TYPE,$msgType,1024,$message); echo "{$message} | consumer({$pid}) destroy \n"; $rand = rand(1,3); sleep($rand); } } function createProgress($callback){ $pid = pcntl_fork(); if ( $pid == -1) { // Creation failed exit("fork progress error!\n"); } else if ($pid == 0) { // Subprocess executor $pid = posix_getpid(); $callback(); exit("({$pid})child progress end!\n"); }else{ // Parent process executor return $pid; } } // 3 write processes for ($i = 0; $i < 3; $i ++ ) { $pid = createProgress('producer'); $childList[$pid] = 1; echo "create producer child progress: {$pid} \n"; } // 2 write processes for ($i = 0; $i < 2; $i ++ ) { $pid = createProgress('consumer'); $childList[$pid] = 1; echo "create consumer child progress: {$pid} \n"; } // Wait for all child processes to finish while(!empty($childList)){ $childPid = pcntl_wait($status); if ($childPid > 0){ unset($childList[$childPid]); } } echo "({$parentPid})main progress end!\n";
Since only one process can access the data in the message queue, no additional locks or semaphores are required.
2. Semaphores and shared memory
Semaphore: it is an atomic operation provided by the system. It is a semaphore. At the same time, only one process can operate. When a process obtains a semaphore, it must be released by the process.
Shared memory: it is a common memory area opened up by the system in the memory. Any process can access it. At the same time, multiple processes can access the area. In order to ensure the consistency of data, it is necessary to lock or semaphore the memory area.
Next, create multiple processes to modify the same value in memory.
echo "parent progress pid:{$parentPid}\n"; $childList = array(); // Create shared memory, create semaphores, and define shared key s $shm_id = ftok(__FILE__,'m'); $sem_id = ftok(__FILE__,'s'); $shareMemory = shm_attach($shm_id); $signal = sem_get($sem_id); const SHARE_KEY = 1; // producer function producer(){ global $shareMemory; global $signal; $pid = posix_getpid(); $repeatNum = 5; for ( $i = 1; $i <= $repeatNum; $i++) { // Get semaphore sem_acquire($signal); if (shm_has_var($shareMemory,SHARE_KEY)){ // Value, plus one $count = shm_get_var($shareMemory,SHARE_KEY); $count ++; shm_put_var($shareMemory,SHARE_KEY,$count); echo "({$pid}) count: {$count}\n"; }else{ // No value, initialization shm_put_var($shareMemory,SHARE_KEY,0); echo "({$pid}) count: 0\n"; } // Run out release sem_release($signal); $rand = rand(1,3); sleep($rand); } } function createProgress($callback){ $pid = pcntl_fork(); if ( $pid == -1) { // Creation failed exit("fork progress error!\n"); } else if ($pid == 0) { // Subprocess executor $pid = posix_getpid(); $callback(); exit("({$pid})child progress end!\n"); }else{ // Parent process executor return $pid; } } // 3 write processes for ($i = 0; $i < 3; $i ++ ) { $pid = createProgress('producer'); $childList[$pid] = 1; echo "create producer child progress: {$pid} \n"; } // Wait for all child processes to end while(!empty($childList)){ $childPid = pcntl_wait($status); if ($childPid > 0){ unset($childList[$childPid]); } } // Free shared memory and semaphores shm_remove($shareMemory); sem_remove($signal); echo "({$parentPid})main progress end!\n";
3. Signal
A signal is a system call. Usually, the kill command we use is to send a signal to a process. Specific signals can be checked by running kill -l in liunx/mac. In the following example, the parent process waits for 5 seconds and sends a sign signal to the child process. The sub process captures the signal and drops the signal processing function for processing.
echo "parent progress pid:{$parentPid}\n"; // Define a signal processing function function sighandler($signo) { $pid = posix_getpid(); echo "{$pid} progress,oh no ,I'm killed!\n"; exit(1); } $pid = pcntl_fork(); if ( $pid == -1) { // Creation failed exit("fork progress error!\n"); } else if ($pid == 0) { // Subprocess executor // Register signal processing function declare(ticks=10); pcntl_signal(SIGINT, "sighandler"); $pid = posix_getpid(); while(true){ echo "{$pid} child progress is running!\n"; sleep(1); } exit("({$pid})child progress end!\n"); }else{ // Parent process executor $childList[$pid] = 1; // After 5 seconds, the parent process sends a sign signal to the child process sleep(5); posix_kill($pid,SIGINT); sleep(5); } echo "({$parentPid})main progress end!\n";
4. Pipeline (famous pipeline)
Pipeline is a common means of multi process communication. Pipeline is divided into nameless pipeline and famous pipeline. Nameless pipeline can only be used for inter process communication with kinship, while famous pipeline can be used for any process on the same host. Only famous pipelines are introduced here. In the following example, the child process writes data and the parent process reads data.
$pipe_path = '/data/test.pipe'; if(!file_exists($pipe_path)){ if(!posix_mkfifo($pipe_path,0664)){ exit("create pipe error!"); } } $pid = pcntl_fork(); if($pid == 0){ // Subprocess, write data to the pipeline $file = fopen($pipe_path,'w'); while (true){ fwrite($file,'hello world'); $rand = rand(1,3); sleep($rand); } exit('child end!'); }else{ // Parent process, reading data from pipeline $file = fopen($pipe_path,'r'); while (true){ $rel = fread($file,20); echo "{$rel}\n"; $rand = rand(1,2); sleep($rand); } }
I hope the above contents can help you. More free PHP manufacturers PDF, PHP advanced architecture video materials, PHP wonderful articles can be searched on wechat. Attention: PHP open source community
2021 gold, silver and four major factories interview true questions collection, must see!
Four years essence PHP technical articles collation Collection - PHP framework article
Four years essence PHP technology collection - micro service architecture chapter
Four years essence PHP technology collection - distributed architecture chapter
Four years essence PHP technology collection - high concurrency scenario
Four years essence PHP technical articles collation Collection - database articles