swoole provides a process management module Process for us to replace the pcntl PHP extensions to help us to create inter-process communication, process management, and processes.
swoole provides communication between the two kinds of processes:
1, conduit based pipe unix socket.
2, based sysvmsg message queue.
We can quickly create by new swoole_process () a process by default will create a SOCK_DGRAM types of pipes for inter-process communication, of course, can be set to other types may not be created.
First, interprocess communication via synchronous blocking pipes
? <PHP $ worker_process_nums = 5; $ worker_process = []; for ($ i = 0; $ i <$ worker_process_nums; $ i ++) { // create a child process // default for each child process creates a pipe, if you do not want to create setting the parameters for the $ pipe_type false // Note that the default is synchronous blocking pipes, half-duplex, if not read data will block $ worker = new new swoole_process (function ($ swoole_process worker) { // Note that if the main process is not write data write (), then the child process here read () will block $ task = json_decode ($ worker-> read (), to true); // perform computing tasks $ tmp = 0; for ($ i = $ task [ 'Start']; $ I <$ Task [ 'End']; $ I ++) { $ tmp + = $ I; } echo 'child process PID:', $ worker-> pid , ' calculation', $ task [ ' start '],' - ', $ task [' end '],' results: ', $ tmp,Value is PHP_EOL; Results // writing into the calculation conduit $ worker-> the Write ($ tmp); // child process exits $ worker-> Exit (); }); // save the child process $ worker_process [$ i] = $ worker; // start a child process $ worker-> Start (); } // to each child conduit delivery tasks for ($ I = 0; $ I <$ worker_process_nums; $ I ++) { $ worker_process [$ I] -> Write (json_encode ([ 'Start' => the mt_rand (. 1, 10), 'End' => the mt_rand (50, 100), ])); } // parent child process exits monitor signal, recovered sub-process, zombie to prevent swoole_process :: signal (SIGCHLD, function ($ SIG) { // must be false, non-blocking mode the while ($ :: RET = swoole_process the wait (to false)) { echo "child process PID: {$ ret [ 'pid ']} exit \ n"; } });
Second, through the pipe to asynchronous swoole_event_add to communicate
? <PHP $ worker_process_nums =. 5; $ worker_process = []; for ($ I = 0; $ I <$ worker_process_nums; $ I ++) { $ worker = new new swoole_process (function ($ worker) { // given in the child Add event listeners conduit // bottom of the duct automatically set nonblocking // two parameters are readable event callback function, a piping can read swoole_event_add ($ worker-> pipe, function ($ pipe) use ( worker $) { $ = Task of json_decode ($ worker-> Read (), to true); $ tmp = 0; for ($ I $ = Task [ 'Start']; $ I <$ Task [ 'End']; $ ++ I) { $ I $ = + tmp; } echo "child process: {$ worker-> pid} $ calculated Task {[ 'Start']} - {$ Task [ 'End']} \ n-"; // child the result of the calculation process, the write pipeline worker- $> the Write ($ tmp); // Note, swoole_event_add and swoole_event_del to be used in pairs swoole_event_del ($ worker-> pipe); // exit the child process $ worker-> Exit (); }); }); $ worker_process [$ I] = $ worker; // start a child process $ worker-> start (); } for ($ I = 0; $ I <$ worker_process_nums; $ I ++) { $ $ worker_process worker = [$ I]; worker- $> Write (json_encode ([ 'Start' => the mt_rand (. 1, 10), 'End' => the mt_rand (50, 100), ])); // the main process, the child process conduit event listener swoole_event_add ( worker- $> pipe, function ($ pipe) use ($ worker) { $ Result = $ worker->read(); echo "child process: {$ worker-> pid} results {$ result} \ n"; swoole_event_del ($ worker-> pipe); }); } // parent child process exits monitor signal, recovered sub-process, to prevent appear zombie process swoole_process :: Signal (SIGCHLD, function ($ SIG) { // must be false, non-blocking mode the while ($ RET :: = swoole_process the wait (false)) { echo "child process PID: {$ ret [ ' pid ']} exit \ n-"; } });
Third, the use of message queues to complete the inter-process communication
? <PHP $ = worker_process_nums. 5; $ worker_process = []; for ($ I = 0; $ I <$ worker_process_nums; $ I ++) { // Note that, here $ pipe_type parameter set to false, indicating that the pipe does not create $ worker swoole_process new new = (function ($ worker) { $ = Task of json_decode ($ worker-> POP (), to true); $ tmp = 0; for ($ I $ = Task [ 'Start']; $ I <$ Task [ 'End']; $ I ++) { $ tmp + = $ I; } echo "child process: {$ worker-> pid} calculate {$ task [ 'start'] } - {$ task [ 'end']} \ n-"; $ worker-> Push ($ tmp); $ worker-> Exit (); }, to false, to false); // using message queues, as inter-process communication // Note that the message queue is shared $ worker -> useQueue (); $worker_process[$i] = $worker; Promoter // process $ worker-> Start (); } for ($ I = 0; $ I <$ worker_process_nums; $ I ++) { // only by sending a message to a child process, because the message queue is shared worker_process $ [0] -> Push (json_encode ([ 'Start' => the mt_rand (. 1, 10), 'End' => the mt_rand (50, 100), ])); } // note here to pause, to prevent Join the task queue, immediately read out the primary process. SLEEP (. 1); for ($ I = 0; $ I <$ worker_process_nums; $ I ++) { $ Result = $ worker_process [0] -> POP (); echo "calculations: {$ Result} \ n-"; } // parent process child process exits monitor signal, the child recovered, prevent zombie swoole_process :: signal (SIGCHLD, function ($ SIG) { // must be false, non-blocking mode while ($ ret = swoole_process :: wait ( false)) { echo "child process PID: {$ ret [ 'pid ']} exit \ n-"; } });
Fourth, the process can set the timer signal by signal monitor, and alarm.
We can set the monitor signal on the parent when the child process exits, re-hang the child process.
You can also set a timer, by swoole_process :: kill ($ pid, 0); timing detection process is alive.
? <PHP // every second trigger signal SIGALAM // note, alarm and can not be used simultaneously Timer swoole_process Alarm :: (1000 * 1000, 0); swoole_process :: Signal (SIGALRM, function ($ signo) { static $ CNT 0 =; $ CNT ++; echo "signal clock timing \ n-"; IF ($ CNT> 10) { // Clear timer swoole_process Alarm :: (-1); } }); swoole_process :: signal (SIGINT, function ( signo $) { echo "I was a ctrl + c \ the n-"; // exit the main process, or would have been unable to exit normally exit (0); });