PHP进程间通信的另外一个手段就是通过 信号 来在进程间传递信息。信号是一种系统调用。通常我们用的kill命令就是发送某个信号给某个进程的。具体有哪些信号可以在liunx/mac中运行kill -l
查看。
一些php信号的意思如下:
SIGHUP 终止进程 终端线路挂断
SIGINT 终止进程 中断进程
SIGQUIT 建立CORE文件终止进程,并且生成core文件
SIGILL 建立CORE文件 非法指令
SIGTRAP 建立CORE文件 跟踪自陷
SIGBUS 建立CORE文件 总线错误
SIGSEGV 建立CORE文件 段非法错误
SIGFPE 建立CORE文件 浮点异常
SIGIOT 建立CORE文件 执行I/O自陷
SIGKILL 终止进程 杀死进程
SIGPIPE 终止进程 向一个没有读进程的管道写数据
SIGALARM 终止进程 计时器到时
SIGTERM 终止进程 软件终止信号
SIGSTOP 停止进程 非终端来的停止信号
SIGTSTP 停止进程 终端来的停止信号
SIGCONT 忽略信号 继续执行一个停止的进程
SIGURG 忽略信号 I/O紧急信号
SIGIO 忽略信号 描述符上可以进行I/O
SIGCHLD 忽略信号 当子进程停止或退出时通知父进程
SIGTTOU 停止进程 后台进程写终端
SIGTTIN 停止进程 后台进程读终端
SIGXGPU 终止进程 CPU时限超时
SIGXFSZ 终止进程 文件长度过长
SIGWINCH 忽略信号 窗口大小发生变化
SIGPROF 终止进程 统计分布图用计时器到时
SIGUSR1 终止进程 用户定义信号1
SIGUSR2 终止进程 用户定义信号2
SIGVTALRM 终止进程 虚拟计时器到时
下面来看一个例子。启动3个子进程,运行,父进程等待5秒钟,向子进程发送sigint信号。子进程捕获信号,调用信号处理函数处理。
<?php
/**
* author: NickBai
* createTime: 2016/12/5 0005 下午 3:01
*/
$parentPid = posix_getpid();
echo "parent progress pid:{$parentPid}\n";
// 定义一个信号处理函数
function sighandler($signo) {
if( $signo == SIGINT ){
$pid = getmypid();
exit("{$pid} progress,oh no ,I'm killed!\n");
}
}
//PHP < 5.3 使用
//配合pcntl_signal使用,表示每执行一条低级指令,就检查一次信号,如果检测到注册的信号,就调用其信号处理器。
//declare(ticks=1);
pcntl_signal( SIGINT, 'sighandler'); //注册信号处理函数
$childList = [];
for( $i = 0; $i < 3; $i++ ){
$pid = pcntl_fork();
if( $pid == 0 ){
while( true ){
//PHP >= 5.3
//调用已安装的信号处理器
//必须在循环里调用,为了检测是否有新的信号等待dispatching。
pcntl_signal_dispatch();
echo "i am child " . getmypid() . " and i am running ! \n";
$sec = rand(1,2);
sleep($sec);
}
}else if( $pid == -1 ){
exit("fork fail!" . PHP_EOL);
}else{
$childList[$pid] = 1;
}
}
sleep(5);
foreach( $childList as $key=>$vo ){
posix_kill( $key, SIGINT ); //触发SIGINIT信号
}
sleep(2);
echo "($parentPid)parent is end " . PHP_EOL;
运行结果如下:
image
参考文章:
http://www.cnblogs.com/zcy_soft/archive/2012/09/21/2697064.html
http://www.jianshu.com/p/08bcf724196b
网友评论