二十四、Swoole 基础学习笔记 - Swoole Process 单进程

作者: 温新

分类: 【Swoole 系列】

阅读: 1513

时间: 2023-03-13 11:52:26

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。

请登录后再评论