Example of creating and using subprocess in process module of PHP spool

Time:2021-4-19

This paper introduces the creation and operation of sub process in the process module of PHP spool. The details are as follows:

Swoole provides us with a process management module process to replace the pcntl extension of PHP, which is convenient for us to create processes, manage processes, and communicate between processes.

Spool provides two kinds of communication between processes

1. Pipe based on UNIX socket.

2. Message queue based on sysvmsg.

We can use new spool? Process () Create a process quickly. By default, a sock? Dgram will be created Type of pipe, used for inter process communication, of course, can be set to other types, also can not create.

1、 Interprocess communication via synchronous blocking pipeline

<?php
$worker_process_nums = 5;
$worker_process = [];
 
for ($i = 0; $i < $worker_process_nums; $i++) {
  //Create child process
  //The default is to create a pipeline for each child process. If you do not want to create a pipeline, set $pipe_ The type parameter is false
  //Note that the default pipeline is synchronous blocking, half duplex, if you can not read the data will block
  $worker = new swoole_process(function (swoole_process $worker) {
    //Note that if the main process does not write the data write (), then the child process will block the read () here
    $task = json_decode($worker->read(), true);
 
    //Carry out the calculation task
    $tmp = 0;
    for ($i = $task['start']; $i < $task['end']; $i++) {
      $tmp += $i;
    }
 
    Echo 'subprocess PID:', $worker - > PID, 'calculation', $task ['Start '],' - ', $task ['end'],'result: ', $TMP, PHP_ EOL;
    //Write the calculated results to the pipeline
    $worker->write($tmp);
    //Subprocess exit
    $worker->exit();
  });
 
  //Save child process
  $worker_process[$i] = $worker;
 
  //Start child process
  $worker->start();
}
 
//Posts tasks to each subprocess pipeline
for ($i = 0; $i < $worker_process_nums; $i++) {
  $worker_process[$i]->write(json_encode([
    'start' => mt_rand(1, 10),
    'end' => mt_rand(50, 100),
  ]));
}
 
//The parent process monitors the exit signal of the child process, recycles the child process, and prevents the zombie process
swoole_process::signal(SIGCHLD, function ($sig) {
  //Must be false, non blocking mode
  while ($ret = swoole_process::wait(false)) {
    Echo "subprocess PID: {$RET ['pid ']} quits from the system;
  }
});

2、 Through spool? Event? Add Make the pipe asynchronous to communicate

<?php
$worker_process_nums = 5;
$worker_process = [];
 
for ($i = 0; $i < $worker_process_nums; $i++) {
  $worker = new swoole_process(function ($worker) {
    //Add event listening to pipeline in subprocess
    //The underlying layer automatically sets the pipe to non blocking mode
    //Parameter 2 is a readable event callback function, indicating that the pipeline can be read
    swoole_event_add($worker->pipe, function ($pipe) use ($worker) {
      $task = json_decode($worker->read(), true);
 
      $tmp = 0;
      for ($i = $task['start']; $i < $task['end']; $i++) {
        $tmp += $i;
      }
      Echo "subprocess: {$worker - > PID} compute {$task ['Start ']} - {$task ['end']} n ';
      //The subprocess writes the result of calculation into the pipeline
      $worker->write($tmp);
      //Attention, spool_ event_ Add and spool_ event_ Del should be used in pairs
      swoole_event_del($worker->pipe);
      //Exit subprocess
      $worker->exit();
    });
  });
 
  $worker_process[$i] = $worker;
 
  //Start child process
  $worker->start();
}
 
for ($i = 0; $i < $worker_process_nums; $i++) {
  $worker = $worker_process[$i];
 
  $worker->write(json_encode([
    'start' => mt_rand(1, 10),
    'end' => mt_rand(50, 100),
  ]));
 
  //In the main process, listen to the sub process pipeline events
  swoole_event_add($worker->pipe, function ($pipe) use ($worker) {
    $result = $worker->read();
    Echo "subprocess: {$worker - > PID} calculation result {$result} n";
    swoole_event_del($worker->pipe);
  });
}
 
//The parent process monitors the exit signal of the child process, recycles the child process, and prevents the zombie process
swoole_process::signal(SIGCHLD, function ($sig) {
  //Must be false, non blocking mode
  while ($ret = swoole_process::wait(false)) {
    Echo "subprocess PID: {$RET ['pid ']} quits from the system;
  }
});

3、 Using message queue to complete interprocess communication

<?php
$worker_process_nums = 5;
$worker_process = [];
 
for ($i = 0; $i < $worker_process_nums; $i++) {
  //Note that the $pipe parameter is changed here_ If type is set to false, the pipeline will not be created
  $worker = new swoole_process(function ($worker) {
    $task = json_decode($worker->pop(), true);
 
    $tmp = 0;
    for ($i = $task['start']; $i < $task['end']; $i++) {
      $tmp += $i;
    }
    Echo "subprocess: {$worker - > PID} compute {$task ['Start ']} - {$task ['end']} n ';
    $worker->push($tmp);
    $worker->exit();
  }, false, false);
 
  //Use message queue as communication between processes
  //Note that message queuing is shared
  $worker->useQueue();
 
  $worker_process[$i] = $worker;
 
  //Start child process
  $worker->start();
}
 
for ($i = 0; $i < $worker_process_nums; $i++) {
  //Only one child process is needed to send the message, because the message queue is shared
  $worker_process[0]->push(json_encode([
    'start' => mt_rand(1, 10),
    'end' => mt_rand(50, 100),
  ]));
}
 
//Note that you need to pause here to prevent the tasks that join the queue from being read out by the main process immediately.
sleep(1);
 
for ($i = 0; $i < $worker_process_nums; $i++) {
  $result = $worker_process[0]->pop();
  Echo "calculated result: {$result} n";
}
 
//The parent process monitors the exit signal of the child process, recycles the child process, and prevents the zombie process
swoole_process::signal(SIGCHLD, function ($sig) {
  //Must be false, non blocking mode
  while ($ret = swoole_process::wait(false)) {
    Echo "subprocess PID: {$RET ['pid ']} quits from the system;
  }
});

4、 The process can monitor the signal through signal and set the timer with alarm.

We can set the listening signal on the parent process, and when the child process exits, we can suspend the child process again.

You can also set the timer through the spool_ Process:: Kill ($PID, 0); detect whether the process is alive regularly.

<?php
//Trigger sigalam signal every 1 second
//Note that alarm cannot be used with timer
swoole_process::alarm(1000 * 1000, 0);
 
swoole_process::signal(SIGALRM, function ($signo) {
  static $cnt = 0;
  $cnt++;
  Echo "clock timing signal";
 
  if ($cnt > 10) {
    //Clear timer
    swoole_process::alarm(-1);
  }
});
 
swoole_process::signal(SIGINT, function ($signo) {
  Echo "I was hit by Ctrl + C ';
 
  //Exit the main process, otherwise it will not exit normally
  exit(0);
});

For more information about PHP, readers who are interested in it can see the following topics: summary of PHP network programming skills, summary of PHP socket usage, introductory course of PHP object-oriented programming, tutorial of PHP data structure and algorithm, and summary of PHP programming algorithm

I hope this article is helpful for PHP programming.

Recommended Today

Review of SQL Sever basic command

catalogue preface Installation of virtual machine Commands and operations Basic command syntax Case sensitive SQL keyword and function name Column and Index Names alias Too long to see? Space Database connection Connection of SSMS Connection of command line Database operation establish delete constraint integrity constraint Common constraints NOT NULL UNIQUE PRIMARY KEY FOREIGN KEY DEFAULT […]