二十四、Swoole 基础学习笔记 - Swoole Process 单进程
hi,我是温新,一名PHPer
文章基于 Swoole 5.0.1 版本编写。
**学习目标:学习 Process 基础使用 **
说明:本篇文章结合官方文档编写及参考网络资料编写,虽非全部原创,但也是结合了自己的理解,若转载请附带本文 URL,编写不易,持续编写更不易,谢谢!
Swoole 进程模块
Swoole 自己实现了一套进程管理模块,用于替代 PHP 的 pcntl
。
PHP 中已有 pcntl,为什么 Swoole 要自己搞一套?因为 PHP 自带的 pcntl 存在很多不足,如:
- 1、没有提供进程间通信的功能;
- 2、不支持重定向标准输入和输出;
- 3、只提供 fork 原始接口,容易使用错误。
基于 pcntl 存在这些问题,Swoole Process 提供了如下特性:
- 可以方便的实现进程间通讯;
- 支持重定向标准输入和输出,在子进程内
echo
不会打印在屏幕中,而是写入管道,读键盘输入可以重定向为管道读取数据; - 提供
exec
接口,创建的进程可以执行其他程序,与原 PHP 父进程之间可以方便的通信; - 在协程环境中无法使用
Process
模块,可以使用runtime hook
+proc_open
实现。
进程间通信
我们知道进程与进程之间是相互隔离,执行任务时,进程之间互不影响。在实际开发中,很多业务之间需要进程通信,如发送邮件,若子进程发送邮件失败,需要通知主进程等等。
Swoole Process 基础使用
process 开胃甜点案例
<?php
// 24-swoole-process-base-1.php
$process = new Swoole\Process('process_callback');
function process_callback () {
echo 'Swoole Process';
}
$process->start();
对于代码暂时不进行解释,先来看看输出的结果:
Swoole Process[codeing@codeing]$php 24-swoole-process-base-1.php
[codeing@codeing]$Swoole Process
为什么会一前一后?这就需要了解 Swoole Process 实现的进程创建了。如子进程没有结束前,父进程已经退出了,因此输出的形式也就不一样了。父子进程如何区分?
- new Swoole\Process 为进程;
- process_callback 回调函数是子进程。
process 基础案例
<?php
// 24-swoole-process-2.php
// 创建进程(父进程)
$process = new Swoole\Process('process_callback');
// 子进程
function process_callback () {
echo 'Swoole Process' . PHP_EOL;
}
// 启动子进程
$process->start();
// 子进程结束后父进程再退出
// 操作成功会返回一个数组包含子进程的 PID、退出状态码、被哪种信号 KILL
Swoole\Process::wait();
输出结果如下:
$php 24-swoole-process-base-2.php
Swoole Process
$php 24-swoole-process-base-2.php
Swoole Process
现在无论怎么输出,输出的显示都是一样的,原因是使用了 wait
方法。现在学习相关方法:
__construct
Swoole\Process::__construct(callable $function, bool $redirect_stdin_stdout = false, int $pipe_type = SOCK_DGRAM, bool $enable_coroutine = false);
参数:
- function:子进程创建成功后要执行的函数;
- redirect_stdin_stdout:重定向子进程的标准输入和输出。【启用此选项后,在子进程内输出内容将不是打印屏幕,而是写入到主进程管道。读取键盘输入将变为从管道中读取数据。默认为阻塞读取。】
- pipe_type:unixSocket 类型。【启用
$redirect_stdin_stdout
后,此选项将忽略用户参数,强制为1
。如果子进程内没有进程间通信,可以设置为0
】 - enable_coroutine:在
callback function
中启用协程,开启后可以直接在子进程的函数中使用协程 API。
start
含义:执行 fork
系统调用,启动子进程。在 Linux
系统下创建一个进程需要数百微秒时间。
返回值:成功返回子进程的 PID
;失败返回 false。
Swoole\Process->start(): int|false
wait
含义:回收结束运行的子进程。
返回值:操作成功会返回一个数组包含子进程的 PID
、退出状态码、被哪种信号 KILL
;失败返回 false。
Swoole\Process::wait(bool $blocking = true): array|false
exec
含义:执行一个外部程序,此函数是 exec
系统调用的封装。
Swoole\Process->exec(string $execfile, array $args);
参数:
- execfile:指定可执行文件的绝对路径,如: /usr/local/php/bin/php;
- args:
exec
的参数列表。
process 执行外部程序
执行外部程序使用 exce 方法。
<?php
// 24-swoole-process-base-exce.php
$process = new Swoole\Process(function ($worker) {
// 执行一个外部程序
$worker->exec('/usr/local/php8/bin/php', [__DIR__ . '/24-exec.php']);
});
// 启动子进程
$process->start();
// 获取子进程必须在 start() 之后
echo '子进程 ID ' . $process->pid . PHP_EOL;
Swoole\Process::wait();
新建外部 php 文件
<?php
// 24-exec.php
echo 'Swoole Process exec()' . PHP_EOL;
输出结果:
$php 24-swoole-process-base-exce.php
子进程 ID 75125
Swoole Process exec()
本篇文章学习了 process 的基础使用,下篇文章继续学习 process。