PHP进程信号处理
2018-09-29 03:56:04来源:博客园 阅读 ()
注意:pcntl这个扩展仅在cli/cgi模式下可用。mod_php和php-fpm中不可以使用。在web server环境中不要使用这组函数,因为会导致不可预料的结果。另,windows作为非类unix系统,没有这些函数。
PCNTL 使用ticks来作为信号处理机制(signal handle callback mechanism),可以最小程度地降低处理异步事件时的负载。何谓ticks?Tick 是一个在代码段中解释器每执行 N 条低级语句就会发生的事件,这个代码段需要通过declare来指定。
下面是一个隔5秒发送一个SIGALRM信号,并由signal_handler函数获取,然后打印一个“Caught SIGALRM”的例子:
<?php declare(ticks = 1); function signal_handler($signal) { print "Caught SIGALRM/n"; pcntl_alarm(5); } pcntl_signal(SIGALRM, "signal_handler", true); pcntl_alarm(5); while(true){ ? } ?>
其实官方的pcntl_signal性能极差,主要是PHP的函数无法直接注册到操作系统信号设置中,所以pcntl信号需要依赖tick机制来完成。 pcntl_signal的实现原理是,触发信号后先将信号加入一个队列中。然后在PHP的ticks回调函数中不断检查是否有信号,如果有信号就执行PHP中指定的回调函数,如果没有则跳出函数。 ticks=1表示每执行1行PHP代码就回调此函数。实际上大部分时间都没有信号产生,但ticks的函数一直会执行。 比较好的做法是去掉ticks,转而使用pcntl_signal_dispatch,在代码循环中自行处理信号。
pcntl_signal_dispatch的实现
<?php // 定义一个处理器,接收到SIGINT信号后只输出一行信息 function signalHandler($signo) { switch ($signo) { case SIGUSR1: echo "SIGUSR1\n"; break; case SIGUSR2: echo "SIGUSR2\n"; break; default: echo "unknow"; break; } } ? //安装信号触发器器 pcntl_signal(SIGINT, 'signalHandler'); while (true) { sleep(1); posix_kill(posix_getpid(), SIGUSR1);///向当前进程发送SIGUSR1信号 pcntl_signal_dispatch(); //接收到信号时,调用注册的signalHandler() }
PCNTL的函数:
信号处理
int pcntl_alarm ( int $seconds )
设置一个$seconds秒后发送SIGALRM信号的计数器
bool pcntl_signal(int $signo ,callback $handler [,bool $restart_syscalls=true])
为$signo设置一个处理该信号的回调函数
第一个参数是信号编号 第二个参数是信号发生时回调的PHP函数。 第三个参数是是否restart,是否重新注册此信号。这个参数如果为false,那此信号只注册处理一次。
注意:每次对 pcntl_alarm()的调用都会取消之前设置的alarm信号和sleep()函数。
??下面是一个隔5秒发送一个SIGALRM信号,并由signal_handler函数获取,然后打印一个“Caught SIGALRM”的例子:
<?php declare(ticks = 1); function signal_handler($signal) { print "Caught SIGALRM/n"; pcntl_alarm(5); } pcntl_signal(SIGALRM, "signal_handler", true); pcntl_alarm(5); for(;;) { } ?>
执行程序
void pcntl_exec ( string $path [, array $args [, array $envs ]] )
在当前的进程空间中执行指定程序,类似于c中的exec族函数。所谓当前空间,即载入指定程序的代码覆盖掉当前进程的空间,执行完该程序进程即结束。
<?php $dir = '/home/test/'; $cmd = 'ls'; $option = '-l'; $pathtobin = '/bin/ls'; $arg = array($cmd, $option, $dir); pcntl_exec($pathtobin, $arg); echo '123'; //不会执行到该行 ?>
创建进程
int pcntl_fork ( void ) 为当前进程创建一个子进程 int pcntl_wait ( int &$status [, int ?$options ] ) 阻塞当前进程,只到当前进程的一个子进程退出或者收到一个结束当前进程的信号。 int pcntl_waitpid ( int $pid , int &$status [, int $options ] ) 功能同pcntl_wait,区别为waitpid为等待指定pid的子进程。当pid为-1时pcntl_waitpid与pcntl_wait一样。
在 pcntl_wait和pcntl_waitpid两个函数中的$status中存了子进程的状态信息,这个参数可以用于 pcntl_wifexited、pcntl_wifstopped、pcntl_wifsignaled、pcntl_wexitstatus、 pcntl_wtermsig、pcntl_wstopsig、pcntl_waitpid这些函数。
举个例子??
<?php $pid = pcntl_fork(); if($pid) { pcntl_wait($status); $id = getmypid(); echo "parent process,pid {$id}, child pid {$pid}/n"; } else { $id = getmypid(); echo "child process,pid {$id}/n"; sleep(2); } ?>
子进程在输出child process等字样之后sleep了2秒才结束,而父进程阻塞着直到子进程退出之后才继续运行。
进程优先级
int pcntl_getpriority ([ int $pid [, int $process_identifier ]] ) 取得进程的优先级,即nice值,默认为0。不同的系统类型以及内核版本下 优先级可能不同(手册中为-20到20) bool pcntl_setpriority ( int $priority [, int $pid [, int $process_identifier ]] ) 设置进程的优先级
参考资料
标签:
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有
上一篇:PHP常用函数代码详细解析
下一篇:Php图像处理书写代码的详细教程
- PHP写UltraEdit插件脚本实现方法 2020-03-29
- php 带逗号千位符数字的处理方法 2020-03-28
- PHP三元运算符的结合性介绍 2020-03-28
- PHP静态延迟绑定和普通静态效率的对比 2020-03-28
- 基于php流程控制语句和循环控制语句 2020-03-28
IDC资讯: 主机资讯 注册资讯 托管资讯 vps资讯 网站建设
网站运营: 建站经验 策划盈利 搜索优化 网站推广 免费资源
网络编程: Asp.Net编程 Asp编程 Php编程 Xml编程 Access Mssql Mysql 其它
服务器技术: Web服务器 Ftp服务器 Mail服务器 Dns服务器 安全防护
软件技巧: 其它软件 Word Excel Powerpoint Ghost Vista QQ空间 QQ FlashGet 迅雷
网页制作: FrontPages Dreamweaver Javascript css photoshop fireworks Flash