lucinda/process

轻量级API,使用IO多路复用来执行单个/多个shell命令

v2.0.3 2022-06-05 07:34 UTC

This package is auto-updated.

Last update: 2024-09-05 12:30:15 UTC


README

此API是PHP proc_*函数的轻量级封装,能够单独执行shell进程、聚合它们或处理穿越它们的流。其设计目标是

  • 平台无关性:API不对运行在操作系统中的进程做任何假设
  • 最小假设原则:API不对处理进程流的方式做任何假设,因此提供了一个框架
  • 优雅和简单:API基于“少即是多”的原则编写,易于理解且易于扩展

API 100%通过单元测试,完全符合PSR-4规范,仅需要PHP 8.1+解释器。安装时,只需在控制台输入以下内容

composer require lucinda/process

然后使用提供的其中一个主要类(使用use Lucinda\Shell命名空间)

  • Stream:封装一个用于进程的数据流(例如:STDIN/STDOUT/STDER)。由
    • Stream\Pipe:封装一个无命名的管道流,立即进行处理
    • Stream\File:封装一个将数据委托给磁盘上文件的流
    • Stream\Resource:封装一个将数据委托给资源的流(例如:套接字)
  • Process:封装一个使用上述Stream实例的单个进程
  • Pool:封装一个进程池,用于并行执行,使用Process\Multiplexer实现进行处理

上述每个类都通过其方法分支到更深入的类,这些类根据进程执行逻辑的复杂度变得相关。为了简化事情,提供了以下驱动程序(使用Lucinda\Shell\Driver命名空间)

这两个类都使用了I/O多路复用,底层使用SELECT命令。

执行单个进程

要执行单个shell命令,可以使用Lucinda\Shell\Process进行精细控制,或使用提供的Lucinda\Shell\Driver\SingleCommandRunner驱动程序

use Lucinda\Shell\Driver\SingleCommandRunner;
use Lucinda\Shell\Process;

$object = new SingleCommandRunner(5);
$result = $object->run(new Process("YOUR_SHELL_COMMAND"));

这比shell_exec更优越,因为它会

  • 如果shell命令执行超过5秒则终止
  • 使用I/O多路复用分别处理STDOUT/STDERR流
  • 并行使用块读取流
  • 自动转义shell命令

执行多个进程

要同时执行多个shell命令,您可以实现自己的Lucinda\Shell\Process\Multiplexer以进行分钟控制或使用提供的Lucinda\Shell\Driver\MultiCommandRunner驱动程序

use Lucinda\Shell\Driver\MultiCommandRunner;
use Lucinda\Shell\Process;

$object = new MultiCommandRunner(5);
$results = $object->run([
  new Process("YOUR_SHELL_COMMAND1"),
  new Process("YOUR_SHELL_COMMAND2"),
  ...
]);

这将

  • 同时打开进程
  • 如果任何一个进程超过5秒,则终止
  • 使用非阻塞方法,允许并行处理流
  • 自动转义shell命令

池化多路复用进程

以固定大小的池(例如此例中的5)运行多路复用进程

use Lucinda\Shell\Driver\MultiCommandRunner;
use Lucinda\Shell\Process;
use Lucinda\Shell\Pool;

# defines a pool of max 5 capacity
$pool = new Pool(5);
# adds processes to pool
$pool->submit(new Process("YOUR_SHELL_COMMAND1"));
$pool->submit(new Process("YOUR_SHELL_COMMAND2"));
...
# executes processes in batches, delegating to Multiplexer instances
$results = $pool->shutdown(new MultiCommandRunner(5));

这将

  • 同时执行N个进程(以上示例中的5个)
  • 当它们全部结束时,进行下一批处理