Swoole Process Manager

Swoole process manager can be used to replace PHP pcntl extension. Compare with PHP pcntl, Swoole process manager provides more features:

public Swoole\Process::__construct ( callable $callback [, boolean $redirect_stdin_and_stdout [, integer $pipe_type ]] )

Alias: swoole_process->__construct( callable $callback [, boolean $redirect_stdin_and_stdout [, integer $pipe_type ]] )

<?php
swoole_process swoole_process->__construct(mixed $function, bool $redirect_stdin_stdout = false, int $create_pipe = 2);

Construct a child process with the callback function executed in the child process, optionally redirect the standard I/O to pipes between the parent process and the child processes.

When the parent process is stopped, the child processes will receive CLOSE event from the pipe.

Parameter

Return

The object of swoole_process

Example

<?php
$process = new swoole_process(function($process){
    echo "the pid of child process is " . $worker->pid . "\n";
    echo "the file descriptor of pipe is " . $worker->pipe . "\n";
    $process->write("hello");
}, false, true);

$process->start();

usleep(100);

echo $process->read();

public void Swoole\Process::start ( void )

Alias: swoole_process->start()

<?php
swoole_process->start();

Fork the swoole child process constructed and return the PID of the child process, or return false if the fork is failed.

Attributes of the child process:

<?php
$process->pid  // the pid of child process
$process->pipe // the file descriptor of pipe

Return

the pid of child process, or return false if the fork is failed. You can use swoole_errno and swoole_strerror to get the code and information of error.

Example

<?php
$workers = [];
$worker_num = 3;

for($i=0;$i<$worker_num ; $i++){

    $process = new swoole_process('process');
    $pid = $process->start();
    $workers[$pid] = $process;

    echo "create a child process\n";
}

foreach($workers as $process)
{
    swoole_event_add($process->pipe, function ($pipe) use($process){
        $data = $process->read();
        echo "RECV: " . $data . "\n";
    });
}

function process(swoole_process $process){
    sleep(rand(5, 10)); 
    $process->write($process->pid);
    echo $process->pid . "\n";
}

public void Swoole\Process::name ( string $process_name )

Alias: swoole_process->name( string $process_name )

<?php
swoole_process->name(string $new_process_name);

Set name of the process started.

After the call of swoole_process->call, the name will be resetted

Parameter

Example

<?php
$process = new swoole_process(function($worker){
    echo "the pid of child process is " . $worker->pid . "\n";
    echo "the file descriptor of pipe is " . $worker->pipe . "\n";

    $worker->write("Hello main process\n");

    $worker->name("php child process"); // set name of the process

    sleep(100);
}, false, true);

$process->start();

usleep(100);

echo $process->read();

public void Swoole\Process::exec ( string $exec_file , string $args )

Alias: swoole_process->exec( string $exec_file , string $args )

<?php
bool swoole_process->exec(string $execfile, array $args)

Execute system commands:

The process will be replaced to be the system command process, but the pipe between the parent process will be kept.

If it needs to communication between the main process and child process, it must enable the redirection of stdin and stdout of child process.

Parameter

Return

bool

Example

<?php
// main process
$process = new swoole_process(function($process){
    //execute the external program
    $process->exec("/usr/bin/php", array('/code/swoole/process/testexec.php'));
}, true); // enable the redirection of stdin and stdout

$process->start();

//Inter-Process Communication Of main process and child process by stdin and stdout

$process->write("hello child process from main process");

$res = $process->read();

var_dump($res);

<?php
// /code/swoole/process/testexec.php 
$fd = fopen('php://stdin', 'r');
$res = fread($fd, 123);
echo "the message from main process" . $res;

public integer Swoole\Process::write ( string $data )

Alias: swoole_process->write( string $data )

<?php
integer swoole_process->write(string $data);

Write data into the pipe and communicate with the parent process or child processes.

Parameter

Return

The length of data sent

Example

<?php
$process = new swoole_process(function($worker){
    echo "the pid of child process is " . $worker->pid . "\n";
    echo "the file descriptor of pipe is " . $worker->pipe . "\n";

    $res = $worker->write("Hello main process\n");
    var_dump(strlen("Hello main process\n"));
    var_dump($res);

    $worker->name("php child process");
}, false, 2);

$process->start();

usleep(100);

echo $process->read();

public boolean Swoole\Process::useQueue ( integer $key [, integer $mode ] )

Alias: swoole_process->useQueue( integer $key [, integer $mode ] )

Prototype

<?php
bool swoole_process->useQueue(int $msgkey = 0, int $mode = 2);

Create a message queue as the communication method between the parent process and child processes.

It can't use the pipe and message queue the same time.

Before the start of the swoole process, it can also call the method push and pop

Parameter

Return

bool

Example

<?php
$child_num = 3;
$child_processes = [];
for($i = 1; $i <= $child_num; $i++)
{
    $process = new swoole_process(function($worker){
        echo "the pid of child process is " . $worker->pid . "\n";

        $worker->name("php child process");

        $recv = $worker->pop();

        echo "To child process " . $worker->pid .  " : " . $recv;

        echo "the child process " . $worker->pid . " exited\n";

        exit(0);
    }, false, false);

    $res = $process->useQueue(0, 2);

    $pid = $process->start();

    $child_processes[(string)$pid] = $process;
}

foreach($child_processes as $pid => $child_process)
{
    $child_process->push("From main process : Hello child process {$pid}\n");
}

public array Swoole\Process::statQueue ( void )

Alias: swoole_process->statQueue()

<?php
array swoole_process->statQueue();

Get the stats of the message queue used as the communication method between processes.

Parameter

void

Return

The array of message queue

<?php
array(
    "queue_num" => 10, // number of task in the queue
    "queue_bytes" => 161, // the total bytes of data in the queue
);

Example

<?php
$child_num = 3;
$child_processes = [];
for($i = 1; $i <= $child_num; $i++)
{
    $process = new swoole_process(function($worker){
        echo "the pid of child process is " . $worker->pid . "\n";

        $worker->name("php child process");

        exit(0);
    }, false, false);

    $res = $process->useQueue(0, 2);

    $pid = $process->start();

    $child_processes[(string)$pid] = $process;
}

foreach($child_processes as $pid => $child_process)
{
    $child_process->push("From main process : Hello child process {$pid}\n");

    echo "the stat of queue : ";

    var_dump($child_process->statqueue());
}

public void Swoole\Process::freeQueue ( void )

Alias: swoole_process->freeQueue()

<?php
swoole_process->freeQueue();

Destory the message queue created by swoole_process->useQueue(int $msgkey = 0, int $mode = 2).

public boolean Swoole\Process::push ( string $data )

Alias: swoole_process->push(string $data)

<?php
bool swoole_process->push(string $data);

Write and push data into the message queue.

Parameter

Return

If failed, it returns false. Or it returns true.

In the blocking mode, if the queue is full, the call of this method will block.

In the non-blocking mode, if the queue is full, the call of this method will return false immediately.

Example

<?php

$workers = [];
$worker_num = 2;

for($i = 0; $i < $worker_num; $i++)
{
    $process = new swoole_process('callback_function', false, false);
    $process->useQueue();
    $pid = $process->start();
    $workers[$pid] = $process;
}

function callback_function(swoole_process $worker)
{
    echo "Child process started, PID=".$worker->pid."\n";
    //recv data from the parent process
    $recv = $worker->pop();
    echo "Data received from the parent process: $recv\n";
    sleep(2);
    $worker->exit(0);
}

foreach($workers as $pid => $process)
{
    $process->push("hello child process [$pid]\n");
}

for($i = 0; $i < $worker_num; $i++)
{
    $ret = swoole_process::wait();
    $pid = $ret['pid'];
    unset($workers[$pid]);
    echo "Child process exit, PID=".$pid.PHP_EOL;
}

public mixed Swoole\Process::pop ([ integer $maxsize ] )

Alias: swoole_process->pop([ integer $maxsize ] )

<?php
string swoole_process->pop(int $maxsize = 8192);

Read and pop data from the message queue.

Parameter

Return

if failed, it returns false. Or it returns the data.

In the blocking mode, if the queue is empty, the call of this method will block.

In the non-blocking mode, if the queue is empty, the call of this method will return false immediately and set the error code to ENOMSG.

public void Swoole\Process::close ( void )

Alias: swoole_process->close()

<?php
bool swoole_process->close();

Close the pipe of the child process.

Return

bool

public void Swoole\Process::exit ([ string $exit_code ] )

Alias: swoole_process->exit([ string $exit_code ] )

<?php
int swoole_process->exit(int $status=0);

Stop the child process.

Parameter

Return

int

Example

<?php
$child_num = 3;
$child_processes = [];
for($i = 1; $i <= $child_num; $i++)
{
    $process = new swoole_process(function($worker){
        echo "the pid of child process is " . $worker->pid . "\n";

        $worker->name("php child process");

        sleep(rand(2, 6));

        $worker->exit(rand(1, 255));
    }, false, false);

    $res = $process->useQueue(0, 2);

    $pid = $process->start();

    $child_processes[(string)$pid] = $process;
}

foreach($child_processes as $child_process)
{
    $ret = swoole_process::wait();
    var_dump($ret);
}

public static void Swoole\Process::kill ( integer $pid [, string $signal_no ] )

Alias: swoole_process::kill( integer $pid [, string $signal_no ] )

<?php
bool swoole_process::kill($pid, $signo = SIGTERM);

Send signal to the child process.

Parameter

Return

if sends signal successfully, it returns true, otherwise it returns false.

Example

<?php
$child_num = 3;
$child_processes = [];
for($i = 1; $i <= $child_num; $i++)
{
    $process = new swoole_process(function($worker){
        echo "the pid of child process is " . $worker->pid . "\n";

        $worker->name("php child process");

        sleep(rand(20, 60));

    }, false, false);

    $res = $process->useQueue(0, 2);

    $pid = $process->start();

    $child_processes[(string)$pid] = $process;
}

sleep(5);

foreach($child_processes as $pid => $child_process)
{
    $ret = swoole_process::kill($pid);
    var_dump($ret);

    $ret = swoole_process::wait();
    var_dump($ret);
}

public static array Swoole\Process::wait ([ boolean $blocking ] )

Alias: swoole_process::wait([ boolean $blocking ] )

<?php
array swoole_process->wait(bool $blocking = true);

Wait for the events of child processes.

Parameter

Return

array, it contains the exit code, pid and signal of child process.

<?php
array('code' => 0, 'pid' => 15001, 'signal' => 15);

Example

<?php
$child_num = 3;
$child_processes = [];
for($i = 1; $i <= $child_num; $i++)
{
    $process = new swoole_process(function($worker){
        echo "the pid of child process is " . $worker->pid . "\n";

        $worker->name("php child process");

        sleep(rand(2, 6));

        $worker->exit(rand(1, 255));

    }, false, false);

    $res = $process->useQueue(0, 2);

    $pid = $process->start();

    $child_processes[(string)$pid] = $process;
}

$i = 1;

swoole_process::signal(SIGCHLD, function($sig) use (&$i){
        // there may be multi processes which exit at the same time
        while($ret = swoole_process::wait(false)){
            var_dump($ret);
        }

        var_dump($i);

        if($i >= 3)
        {
            exit(0);
        }

        $i++;
    }
);

echo "Wait for exit of child process\n";

public static void Swoole\Process::daemon ([ boolean $nochdir [, boolean $noclose ]] )

Alias: swoole_process::daemon([ boolean $nochdir [, boolean $noclose ]] )

<?php
bool swoole_process->daemon(bool $nochdir = true, bool $noclose = true);

Change the process to be a daemon process.

Parameter

Return

bool

public static void Swoole\Process::signal ( string $signal_no , callable $callback )

Alias: swoole_process::signal( string $signal_no , callable $callback )

<?php
bool swoole_process->signal(int $signo, callable $callback);

Setup signal callback function.

Parameter

Return

bool

public static void Swoole\Process::alarm ( integer $interval_usec )

Alias: swoole_process::alarm( integer $interval_usec )

<?php
bool swoole_process->alarm(int $interval_usec, int $type = ITIMER_REAL)

High precision timer which will trigger signal every fixed interval.

Parameter

Return

bool

Example

<?php
swoole_process::signal(SIGALRM, function () {
    static $i = 0;
    echo "#{$i}\talarm\n";
    $i++;
    if ($i > 20) {
        swoole_process::alarm(-1);
    }
});

//100ms
swoole_process::alarm(100 * 1000);

public static void Swoole\Process::setaffinity(array $cpu_set)

Alias: swoole_process::setaffinity(array $cpu_set)

<?php
bool swoole_process->setaffinity(array $cpu_set)

Set the CPU affinity of the process.

Parameter

Return

true : success, false : fail