PHP CLI模式下PCNTL扩展实现多进程服务的例子

PHP可通过PCNTL扩展实现进程控制,如进程创建,信号处理,进程中断判断等。但只能在CLI模式下操作。
PCNTL的信号机制是基于 ticks 机制实现的。因此在使用信号相关函数时需要在前面添加declare(ticks = n) 语法结构。
pcntl_alarm ( int $seconds )指定秒数后向进程发送一个 SIGALRM 信号
pcntl_signal ( int $signo , callback $handler [, bool $restart_syscalls ])给指定信号$signo设置回调函数
declare(ticks = 1);
 
function signal_handler($signal) {
    print "Caught SIGALRM\n";
    pcntl_alarm(3);
}
 
pcntl_signal(SIGALRM, "signal_handler", true);
pcntl_alarm(3);
 
for(;;) {
}

pcntl_exec ( string $path [, array $args [, array $envs ]] )执行指定命令,执行完即结束,后面将不会执行
$dir = '/root/';
$cmd = 'ls';
$option = '-l';
$pathtobin = '/bin/ls';
 
$arg = array($cmd, $option, $dir);
pcntl_exec($pathtobin, $arg);
 
echo 'will not exec here';

pcntl_fork ( void )为当前进程fork子进程
此时,父进程执行过程中,得到的fork返回值为子进程号(>0),失败时,在 父进程上下文返回-1,不会创建子进程,并且会引发一个PHP错误;
父进程的阻塞同时会阻塞子进程。但是父进程的结束不影响子进程的运行;
子进程会从执行pcntl_fork()的那条语句开始执行(包括此函数),但是此时它返回的是零(代表这是一个子进程)。在子进程的代码块中最好有exit语句,即执行完子进程后立即就结束。
int pcntl_wait ( int &$status [, int $options = 0 ] ) 等待或返回fork的子进程状态
说明子进程调用结束后,并没有完全销毁,而是变成了僵尸进程,不占内存,仅存在进程列表。此时需要调用父进程调用wait来等待子进程结束。如果父进程在子进程前退出了,那么init进程将会对僵尸进程进行管理,它还是可以被清除的。第二个参数可设置阻塞方式:
1. WUNTRACED 阻塞方式调用的,函数返回值为子进程的pid,如果没有子进程返回值为-1;
2. WNOHANG 非阻塞方式调用,函数还可以在有子进程在运行但没有结束的子进程时返回0。
$pid  =  pcntl_fork ();
//父进程和子进程都会执行下面代码
if ( $pid  == -1 ) {
    //错误处理:创建子进程失败时返回-1.
    die( 'could not fork' );
} else if ( $pid ) {
    //父进程会得到子进程号,所以这里是父进程执行的逻辑
    pcntl_wait ($status, WUNTRACED);  //等待子进程中断,防止子进程成为僵尸进程。
    echo "ok".PHP_EOL;
} else if ($pid == 0){
    //子进程得到的$pid为0, 所以这里是子进程执行的逻辑。
    echo "子进程运行" . getmypid() .PHP_EOL;
    sleep(5);
    exit;
}
 
echo "父进程运行" . getmypid() .PHP_EOL;

时间: 2024-09-14 15:14:48

PHP CLI模式下PCNTL扩展实现多进程服务的例子的相关文章

PHP CLI模式下的多进程应用分析

PHP在很多时候不适合做常驻的SHELL进程, 他没有专门的gc例程, 也没有有效的内存管理途径. 所以如果用PHP做常驻SHELL, 你会经常被内存耗尽导致abort而unhappy 而且, 如果输入数据非法, 而脚本没有检测, 导致abort, 也会让你很不开心. 那? 怎么办呢? 多进程-. 为什么呢? 优点: 1. 使用多进程, 子进程结束以后, 内核会负责回收资源 2. 使用多进程,子进程异常退出不会导致整个进程Thread退出. 父进程还有机会重建流程. 3. 一个常驻主进程, 只负

php cli模式下获取参数的方法

本文转自IT摆渡网欢迎转载,请标明出处 更多php文章请阅读 php问题解决 PHP在cli模式下接收参数有两种方法 1.使用argv数组 2.使用getopt方法 1.使用argv数组 例如:需要执行一个php,并传递三个参数(type=news, is_hot=1, limit=5) 创建test.php <?php print_r($argv); ?> 在命令行执行 php test.php news 1 5 输出: Array ( [0] => test.php [1] =>

ThinkPHP在Cli模式下使用模板引擎的方法_php实例

本文实例讲述了ThinkPHP在Cli模式下使用模板引擎的方法.分享给大家供大家参考.具体如下: 关于Cli模式与模版引擎,2.1中的手册是这样说明的: Cli模式默认不使用任何模板引擎(可以自己在操作方法里面调用): 但是怎么调用,手册中没有提到.于是自己动手丰衣足食. 在介绍怎么调用之前,简单的说说什么情况可能需要用到模块引擎: 1. 利用dompdf在计划任务自动生成PDF或HTML报告 2. 计划任务发送HTML类型的邮件 3. 后台自动生成静态页面 4. 其他关于模板的后台操作 <?p

SAS112如何在CLI模式下删除手动创建的主机?

原因分析: SAS112在CLI模式下删除手动创建的主机.但是此方法不能删除发现或映射的主机.对于手动创建的映射主机,必须取消映射,才能删除. 解决方案: delete host 说明:删除手动创建的主机.不删除发现或映射的主机.对于手动创建的映射主机,必须取消映射,才能删除它. 语法:delete host host 参数:host  主机的 ID 或昵称. 示例: 删除手动创建的主机 MyHost: # delete host MyHost Info: Command completed s

php安装pcntl扩展实现多进程

pcntl中php实现多进程必须要安装的扩展,现将扩展安装步骤写在下面.   一.两种安装方式   1.重新编译PHP的后面configrue提示加上?enable-pcntl.2.不重新编译php,直接编译安装pcntl扩展. # cd /usr/local/src/php-5.2.6/ext/pcntl # /usr/local/php/bin/phpize # ./configure ?with-php-config=/usr/local/php/bin/php-config # make

PHP CLI模式下的多进程应用

PHP在很多时候不适合做常驻的SHELl进程, 他没有专门的gc例程, 也没有有效的内存管理途径.所以如果用PHP做常驻SHELL, 你会经常被内存耗尽导致abort而unhappy. 而且, 如果输入数据非法, 而脚本没有检测, 导致abort, 也会让你很不开心. 那? 怎么办呢? 呵呵, 别着急, 多进程来帮您! 那,这是为什么呢? 优点: 1.使用多进程, 子进程结束以后, 内核会负责回收资源 2.使用多进程,子进程异常退出不会导致整个进程Thread退出.父进程还有机会重建流程. 3.

SAS112 CLI模式下删除虚拟磁盘

命令:delete vdisks 说明:删除指定的虚拟磁盘.取消映射虚拟磁盘中的所有卷和快照并将它们删除,同时取消与分配到虚拟磁盘的所有磁盘的关联. 注释: • 如果虚拟磁盘包含快照池,且此快照池与另一虚拟磁盘上的主卷相关联,则不能删除该虚拟磁盘. • 如果您删除了隔离的虚拟磁盘,而稍后找到其缺失的磁盘,则此虚拟磁盘将重新以隔离或脱机形式出现,必须重新将其删除,才能彻底清除这些磁盘. 语法:delete vdisks [prompt yes|no] vdisks 参数:prompt yes|no

SAS112 在CLI模式下如何删除分配给虚拟磁盘的指定热备盘?

命令:delete vdisk-spare   说明:删除分配给虚拟磁盘的指定热备盘.   语法:delete vdisk-spare disks disks   vdisk   参数:disks disks要删除的备用磁盘的 ID,格式为[机箱号.磁盘槽位号].   vdisk要从中删除备用磁盘的虚拟磁盘的名称或序列号.   示例:从虚拟磁盘 VD1 删除备用磁盘 1.5(机箱号为1,磁盘槽位号为5):   # delete vdisk-spare disks 1.5 VD1   Info:

SAS112如何在CLI模式下将快照恢复到初始状态?

delete snapshot-write-data 说明:删除快照修改的数据,将快照恢复为首次抓取时的状态. 语法:delete snapshot-write-data snapshot 参数:snapshot 要从中删除修改数据的快照的名称或序列号. 示例:仅从快照 SS1 中删除已修改数据: # delete snapshot-write-data SS1 Success: Command completed successfully. (SS1) - Snapshot write dat