azielinski / simple-process
PHP pcntl fork 函数的简单封装
dev-master
2015-05-09 13:22 UTC
Requires
- ext-pcntl: *
This package is not auto-updated.
Last update: 2024-09-23 14:49:34 UTC
README
这个小型库使得使用 pcntl
扩展变得简单;强烈建议您也看看 PThreads
库(http://pthreads.org),它比这个微小的封装更强大;我之所以编写它,仅仅是因为在我的使用场景中,使用 PThreads 不是一个选择。
安装
需求
PHP >= 5.3
pcntl extension installed
Composer
只需将以下行添加到您的 "require":
部分
"azielinski/simple-process": "dev-master"
您不使用 composer 吗?
那么只需克隆仓库 :) 您还需要手动 include
所有四个文件。
基本使用
基本使用看起来像这样
declare(ticks=1); // This part is critical, be sure to include it $manager = new SimpleProcess\ProcessManager(); $manager->fork(new SimpleProcess\Process(function() { sleep(5); }, "My super cool process")); do { foreach($manager->getChildren() as $process) { $iid = $process->getInternalId(); if($process->isAlive()) { echo sprintf('Process %s is running', $iid); } else if($process->isFinished()) { echo sprintf('Process %s is finished', $iid); } echo "\n"; } sleep(1); } while($manager->countAliveChildren());
就这样!子进程将只执行提供的可调用函数,因此无需担心“我是否在这个行的正确进程中?”;父进程在调用 ->fork()
后继续正常执行;ProcessManager
类还负责回收子进程,因此您可以专注于应用程序的逻辑,而不是 pcntl_*
函数使用的阴暗角落。
父进程与子进程之间的通信
ProcessManager 可能会为每个子进程分配一些共享内存 - 然后您可以从父进程访问它
declare(ticks=1); // This part is critical, be sure to include it $manager = new SimpleProcess\ProcessManager(); $manager->allocateSHMPerChildren(1000); // allocate 1000 bytes for each forked process for($i=0;$i<4;$i++) { $manager->fork(new SimpleProcess\Process(function(SimpleProcess\Process $currentProcess) { $currentProcess->getShmSegment()->save('status', 'Processing data...'); sleep(5); $currentProcess->getShmSegment()->save('status', 'Connecting to the satellite...'); sleep(5); }, $i)); } $manager->cleanupOnShutdown(); // Register shutdown function that will release allocated shared memory; // It is important to call this after all fork() calls, as we don't want // to release it when child process exits do { foreach($manager->getChildren() as $process) { $iid = $process->getInternalId(); if($process->isAlive()) { echo sprintf('Process %s is running with status "%s"', $iid, $process->getShmSegment()->fetch('status')); } else if($process->isFinished()) { echo sprintf('Process %s finished execution', $iid); } echo "\n"; } sleep(1); } while($manager->countAliveChildren()); $manager->cleanup(); // You can also call cleanup() manually if you want to
其他事项
此库还提供了 Semaphore
类,以防您需要在代码中某处使用信号量;使用方法如下
$s = SimpleProcess\Semaphore::create('critical_section'); $s->acquire(); $s->release();