SWOOLE---进程Process

Swoole 提供的进程管理模块,用来替代 PHP 的 pcntl

此模块比较底层,是操作系统进程管理的封装,使用者需要具备 Linux 系统多进程编程经验。

PHP 自带的 pcntl,存在很多不足,如:

没有提供进程间通信的功能
不支持重定向标准输入和输出
只提供了 fork 这样原始的接口,容易使用错误
Process 提供了比 pcntl 更强大的功能,更易用的 API,使 PHP 在多进程编程方面更加轻松。

Process 提供了如下特性:

可以方便的实现进程间通讯
支持重定向标准输入和输出,在子进程内 echo 不会打印屏幕,而是写入管道,读键盘输入可以重定向为管道读取数据
提供了 exec 接口,创建的进程可以执行其他程序,与原 PHP 父进程之间可以方便的通信
在协程环境中无法使用 Process 模块,可以使用 runtime hook+proc_open 实现,参考协程进程管理


use Swoole\Process;

/*
 * Swoole\Process->__construct(callable $function,子进程创建成功后要执行的函数
 * bool $redirect_stdin_stdout = false, 参数为true,在子进程内 echo 不会打印屏幕,而是写入管道,读键盘输入可以重定向为管道读取数据
 * int $pipe_type = SOCK_DGRAM,
 * bool $enable_coroutine = false);在 callback function 中启用协程,开启后可以直接在子进程的函数中使用协程 API
*/

for ($n = 1; $n <= 3; $n++) {
    $process = new Process(function () use ($n) {
        echo 'Child #' . getmypid() . " start and sleep {$n}s" . PHP_EOL;
        sleep($n);
        echo 'Child #' . getmypid() . ' exit' . PHP_EOL;
    },false);
    $process->start();//执行 fork 系统调用,启动子进程。在 Linux 系统下创建一个进程需要数百微秒时间
}
for ($n = 3; $n--;) {
    $status = Process::wait(true);//回收子进程
    echo "Recycled #{$status['pid']}, code={$status['code']}, signal={$status['signal']}" . PHP_EOL;
}
echo 'Parent #' . getmypid() . ' exit' . PHP_EOL;

/*
 * 执行一个外部程序,此函数是 exec 系统调用的封装。
 * 注意:$execfile 必须使用绝对路径,否则会报文件不存在错误;
由于 exec 系统调用会使用指定的程序覆盖当前程序,子进程需要读写标准输出与父进程进行通信;
如果未指定 redirect_stdin_stdout = true,执行 exec 后子进程与父进程无法通信。
 * */
$process = new Swoole\Process('callback_function', true);

$pid = $process->start();

function callback_function(Swoole\Process $worker)
{
    $worker->exec("/usr/bin/php",[__DIR__.'/../server/http_server.php']);
}

Swoole\Process::wait();

执行结果:

Child #1161 start and sleep 1s
Child #1162 start and sleep 2s
Child #1163 start and sleep 3s
Child #1161 exit
Recycled #1161, code=0, signal=0
Child #1162 exit
Recycled #1162, code=0, signal=0
Child #1163 exit
Recycled #1163, code=0, signal=0
Parent #1160 exit

多进程实例


echo "process_start_time:".date('Y-m-d H:i:s').PHP_EOL;
$workers = [];
$url = [
  'http://baidu.com',
  'http://sina.com.cn',
  'http://qq.com',
];

for ($i = 0 ; $i < 3; $i++){
    //子进程
    $process = new swoole_process(function (swoole_process $worker) use ($i, $url){
        //curl
        $content = curlData($url[$i]);
        //echo $content.PHP_EOL;  //参数为true,写入管道
        $worker->write($content);//写入管道
    },true);
    $pid = $process->start();
    $workers[$pid] = $process;
}

foreach ($workers as $process){
    echo $process->read();//从管道中读取
}

//模拟爬虫
function curlData($url){
    sleep(10);
    return $url."success".PHP_EOL;
}
echo "process_end_time:".date('Y-m-d H:i:s');

执行结果:

process_start_time:2020-05-05 14:52:35
http://baidu.comsuccess
http://sina.com.cnsuccess
http://qq.comsuccess
process_end_time:2020-05-05 14:52:45% 

开启三个进程执行三次模拟爬虫,时间一共10秒,

你可能感兴趣的:(swoole)