How does popen realize multi-process concurrent execution? pclose of loop inside will wait for the process to complete before the next loop

  mysql, question

How does 1.PHP Popen realize multi-process concurrent execution? pclose of circular inside will wait for the process to complete before the next cycle

2. Assuming that there are 17 processes to be started, how to start 5 processes at a time, and close one process at a time when one process is completed, and open the next process at the same time, that is to say, only 5 processes can be executed at most at the same time

//Start 2 Processes
 for($i = 0;  $i < 2;  $i plus)
 $command = "$phpPath $destPHPFile >> $logFile$i";
 Echo "process start time". date('Y-m-d H:i:s')."\n ";
 $resource = popen($command,'r');
 if(is_resource($resource)){
 $success Plus;
 pclose($resource);  //The next cycle will wait for the last process to complete before pclose releases resources.
 Echo date('Y-m-d H:i:s'). "process:". $ i. "is started, executed and closed, opening the next process \n";
 }else{
 $failure plus;
 bracket
 bracket

This approach is equivalent to starting one process at a time and executing it circularly. It is equivalent to processing tasks in a single process. How can multiple processes be achieved?

Thank you for your invitation.

If you have the framework and experience of Message Queue, it is very convenient to realize this.
The consumer channel of Message Queue messages can set prefetch=5, i.e. processing up to 5 messages at the same time
Message Queue also has a perfect ack mechanism, that is, a message receipt (the message has been correctly processed, give me the next message)
Moreover, it will not block your current PHP process, and the background (consumer worker) will slowly finish these tasks in 5 concurrent situations

Simply start with Redis’ List and judge the queue length when it is blocked, and start popen and append to the queue when it is less than 5

test.php

$redis = new \Redis();
 $redis->connect("127.0.0.1", 6379);
 
 $queue_name = "myqueue";
 $queue_prefetch = 5;
 $redis->delete($queue_name);  // delete fro reseting.
 for($i=0;   $i<17;  $i plus)
 while(1){
 $count = count($redis->lRange($queue_name, 0, -1));
 if($count <= $queue_prefetch) break;
 usleep(20);  //Blockage 20ms, depending on the situation, too low redis I/O will be frequent.
 bracket
 $redis->rPush($queue_name, $i);
 $pid = pcntl_fork();  //pcntl module is required to open subprocess
 if($pid){
 pclose(popen("/usr/bin/php /diandao/script.php $i $pid $queue_name", "w"));
 pcntl_wait($status);
 bracket
 bracket

/diandao/script.php

<?  Php
 sleep(1);  //Analog processing exceeds 1 second
 
 $index = $argv[1];
 $pid = $argv[2];
 $queue = $argv[3];
 $redis = new Redis;
 $redis->connect("127.0.0.1", 6379);
 
 $ f = fopen ("/dialado/script.log", "a plus");
 $date = date("Y-m-d H:i:s");
 fwrite($f, "[$date] ".json_encode($argv).PHP_EOL );
 fclose($f);
 $redis->lRem($queue, $index);

Log results
图片描述

Quantity judgment that wrote a = number, so concurrent became 6