Swoole tutorial section 1: process management module (process) – upper

Time:2021-8-24

Process management module


Look hereSwoole process
You can first look at your own version of swoole and type it on the command line

php –ri swoole

More PHP command line use, we learnPHP command line parameters
OK, let’s go straight to the subject
How to use it?

Multi process creation

Not much, just the code

<?php
$worker_ num =2;// Number of processes created
for($i=0;$i<$worker_num ; $i++){
    $process = new swoole_process('callback_function_we_write');
    $pid = $process->start();
    echo PHP_EOL . $pid;//
}
function callback_function_we_write(swoole_process $worker){
    echo  PHP_EOL;
    var_dump($worker);
    echo  PHP_EOL;
}

The operation results are as follows

5445
object(swoole_process)#1 (3) {
  ["pipe"]=>
  int(3)
  ["callback"]=>
  string(26) "callback_function_we_write"
  ["pid"]=>
  int(5445)
}


5446
object(swoole_process)#2 (3) {
  ["pipe"]=>
  int(5)
  ["callback"]=>
  string(26) "callback_function_we_write"
  ["pid"]=>
  int(5446)
}

As you can see, we use new spool_ Process to create a process, you need a parameter, that is, the callback function
When we execute with $process – > start (), we return the PID of the process, that is, $PID
At this point, the subprocess starts, calls the callback function, and passes a parameter, namely, spool_ $worker of type process
I deliberately output $worker to see what’s in it. The result has three properties

The pipe ID of the pipe process will be discussed later when it comes to inter process communication
PID is the PID of the current child process
Callback this is the callback function name we wrote ourselves

Here, we can play with multiple processes,
For example, we can test the running speed of multiple processes

<?php
echo PHP_EOL . time() ;
$worker_ num =3;// Number of processes created
for($i=0;$i<$worker_num ; $i++){
    $process = new swoole_process('callback_function_we_write');
    $pid = $process->start();
}

function callback_function_we_write(swoole_process $worker){
    for($i=0;$i<100000000;$i++){}
    echo PHP_EOL . time() ; 
}

My local operation results

1435563435 / / start time
1435563438 / / end time of process 1
1435563440 / / end time of process 2
1435563440 / / end time of process 3

It takes 5S to calculate three times (in fact, it usually takes 4S)

play again

<?php
echo PHP_EOL . time() ;
for($i=0;$i<100000000;$i++){}
for($i=0;$i<100000000;$i++){}
for($i=0;$i<100000000;$i++){}
echo PHP_EOL . time() ;

My local operation results

1435563704
1435563712

It took 8s this time

After doing this, I want to explain a problem

It doesn’t mean that a single process takes 8s to finish the work. We can reduce the time by three times in three processes

Well, because this is my previous misunderstanding

Multi process can also play like this

<?php
$funcMap=array('methodOne' , 'methodTwo' ,'methodThree' );
$worker_ num =3;// Number of processes created

for($i=0;$i<$worker_num ; $i++){
    $process = new swoole_process($funcMap[$i]);
    $pid = $process->start();
    sleep(2);
}

 while(1){
            $ret = swoole_process::wait();
            If ($RET) {// $RET is an array, and code is the process exit status code,
                $pid = $ret['pid'];
                echo PHP_EOL."Worker Exit, PID=" . $pid . PHP_EOL;
            }else{
                break;
            }
}

function methodOne(swoole_ Process ($worker) {// first process
    echo $worker->callback .PHP_EOL;
}

function methodTwo(swoole_ Process ($worker) {// second process
    echo $worker->callback .PHP_EOL;
}

function methodThree(swoole_ Process ($worker) {// the third process
    echo $worker->callback .PHP_EOL;
}

I added sleep to make it easier to see at runtime. You can also remove it
Here I use swoole_ process::wait()Explain in detail
The purpose is that when the child process ends, the main process can know.

Let’s think about a situation
On the holiday, my mother wants to cook. When I see that the kitchen is short of oil, salt, sugar, monosodium glutamate and thirteen incense. So he ordered his son to buy some from the canteen. I can’t stay idle in the kitchen. My mother should continue to wash and cut vegetables. When the seasoning is bought back, the dishes are washed, cut and fried. When a dish is fried here, it should be sent to the table immediately.

In this scenario, it is obvious that multiple processes are used, and each process does not do the same thing. When the child processes are completed, the main process begins to continue business.

Now there is a problem. Take the above situation for example. When my son goes to buy seasoning, what if he finds that there is no salt or not enough money? How can he contact his mother? That’s what we’re going to sayInterprocess communication

Interprocess communication

There are two ways to communicate with process

The Conduit
swoole_process->write(string $data);
swoole_process->read(int $buffer_size=8192);

Message queue
swoole_process->useQueue();
swoole_process->push(string $data);
swoole_process->pop(int $maxsize = 8192);

Let’s talk about the pipeline first

Pipeline communication

Here, we want to mention the creation of new spool again_ process
Please look hereProcess creation
The first parameter is the callback function, no more
The meaning of the second parameter will be explained with examples
The third parameter is true by default, which means to create a pipeline. Do you remember what I saw when I specifically output $worker in the callback function?

object(swoole_process)#1 (3) {
  ["pipe"]=>
  int(3)
  ["callback"]=>
  string(26) "callback_function_we_write"
  ["pid"]=>
  int(5445)
}

The key is herepipeThis is the pipeline ID of this process
We can understand this

Each time a process is created, a pipeline will be created. The main process will write / read data to the pipeline of that process if it wants to communicate with that process.

OK, let’s look at the code

<?php
$redirect_ stdout = false;//  Redirect output; The purpose of this parameter will see the effect later
$worker_ num = 2;// Number of processes
$workers = [];// For storing processes
for($i = 0; $i < $worker_num; $i++){
    $process = new swoole_process('workerFunc',$redirect_stdout );
    $pid = $process->start();
    $workers[$pid] = $process;// Store the handle of each process
}
//This is the main process.
Foreach ($workers as $PID = > $process) {// $process is the handle of the child process
    $process->write("hello worker[$pid]\n");// The child process handle writes content to its own pipeline $process - > write ($data);
    echo "From Worker: ".$process->read();// The child process handle reads information from its own pipeline $process - > read();
    echo PHP_EOL.PHP_EOL;
 }

function workerFunc(swoole_ Process $worker) {// this is the child process
    $recv = $worker->read();
    echo PHP_EOL. "From Master: $recv\n";
    //send data to master
    $worker->write("hello master , this pipe  is ". $worker->pipe .";  this  pid  is ".$worker->pid."\n");
    sleep(2);
    $worker->exit(0);
}

Paste operation results

From Master: hello worker[8205]

From Worker: hello master , this pipe  is 3;  this  pid  is 8205



From Master: hello worker[8206]

From Worker: hello master , this pipe  is 5;  this  pid  is 8206

Oh, here’s the communication.
First, store the handles of all child processes in an array of the main process, and the index of the array is PID.
When the main process wants to communicate with which process, it uses that handle to write / read data to the corresponding pipeline, so as to realize the communication between processes.

Then, let’s change it a little to see the operation effect

$redirect_ stdout = true;//  Redirect output. Note that I changed it to true this time, but nothing else has changed
$worker_ num = 2;// Number of processes
$workers = [];// For storing processes
for($i = 0; $i < $worker_num; $i++){
    $process = new swoole_process('workerFunc',$redirect_stdout );
    $pid = $process->start();
    $workers[$pid] = $process;// Store the handle of each process
}

//This is the main process.
Foreach ($workers as $PID = > $process) {// $process is the handle of the child process
    $process->write("hello worker[$pid]\n");// The child process handle writes content to its own pipeline $process - > write ($data);
    echo "From Worker: ".$process->read();// The child process handle reads information from its own pipeline $process - > read();
    echo PHP_EOL.PHP_EOL;
 }

function workerFunc(swoole_ Process $worker) {// this is the child process
    $recv = $worker->read();
    echo PHP_EOL. "From Master: $recv\n";
    //send data to master
    $worker->write("hello master , this pipe  is ". $worker->pipe .";  this  pid  is ".$worker->pid."\n");
    sleep(2);
    $worker->exit(0);
}

Output results

From Worker: 
From Master: hello worker[8007]



From Worker: 
From Master: hello worker[8008]

Well, it’s different. Do you have it. Let’s look at the description of the second parameter when creating the process

$redirect_ stdin_ Stdout, redirect the standard input and output of the child process. When this option is enabled, in-process echo will not print the screen, but write to the pipeline. Reading keyboard input will change to reading data from the pipe. The default is blocking reads.

Let me explain. Because true is specified during creation, the echo content in the subprocess will be sent to the pipeline instead of printed on the screen (this is similar to PHP’s OB caching mechanism, let’s imagine)
As mentioned earlier, the process communication is realized by reading / writing data from the pipeline, and the echo content in the sub process is redirected to the pipeline. Therefore, the content read by the main process from the pipeline is the echo content in the sub process.
This results in the above output.

Message queue

Let me start with a linkUsing PHP to operate Linux message queue to complete interprocess communication
The key point is the two link articles in this article. We’ll have a look later
There’s another command

IPCs -q view the current message queue

This part will be discussed next time

Recommended Today

A detailed explanation of the differences between Perl and strawberry Perl and ActivePerl

Perl is the abbreviation of practical extraction and report language “practical report extraction language”. Application of activestateperl and strawberry PERL on Windows platformcompiler。 Perl   The relationship between the latter two is that C language and Linux system have their own GCC. The biggest difference between activestate Perl and strawberry Perl is that strawberry Perl […]