首先我们需要了解几个函数

pcntl_signal   安装信号处理器,也就是当指定信号发生时,调用函数。
pcntl_alarm   指定秒数后向进程发送SIGALRM信号。
posix_getpid 返回当前进程id
posix_kill       给指定进程发送信号
 
一些常用的信号说明
SIGHUP
本信号在用户终端连接(正常或非正常)结束时发出, 通常是在终端的控制进程结束时,
通知同一session内的各个作业, 这时它们与控制终端不再关联。 SIGINT
程序终止(interrupt)信号, 在用户键入INTR字符(通常是Ctrl-C)时发出。 SIGQUIT
和SIGINT类似,但由QUIT字符(通常是Ctrl-/)来控制;进程在因收到SIGQUIT退出时会产生core文件,
在这个意义上类似于一个程序错误信号。 SIGKILL
用来立即结束程序的运行。本信号不能被阻塞、处理和忽略。如果管理员发现某个进程终止不了,可尝试发送这个信号。 SIGTERM
程序结束(terminate)信号, 与SIGKILL不同的是该信号可以被阻塞和处理。通常用来要求程序自己正常退出,
shell命令kill缺省产生这个信号。如果进程终止不了,我们才会尝试SIGKILL。 SIGUSR1
留给用户使用 SIGUSR2
留给用户使用 SIGALRM
时钟定时信号, 计算的是实际的时间或时钟时间。alarm函数使用该信号。 SIGCHLD
子进程结束时, 父进程会收到这个信号。
例1:
<?php
declare(ticks = 1); //信号处理函数
function sig_func() {
echo "child exit \r\n";
} //设置信号处理器
pcntl_signal(SIGCHLD, 'sig_func'); $pid = pcntl_fork(); if($pid == -1) {
die('fork error');
} else if ($pid) {
pcntl_wait($status);
} else {
echo "child... \r\n";
exit;
}

当子进程退出时,会向父进程发送SIGCHLD信号,我们通过设置信号处理器,成功的处理信号。

例2:
<?php
declare(ticks = 1); //信号处理函数
function sig_func($signo) {
switch($signo) {
case SIGCHLD: {
echo "child SIGCHLD \r\n";
break;
}
case SIGTERM: {
echo "child SIGTERM \r\n";
break;
}
default:
//处理所有其他信号
break;
}
} //设置信号处理器
pcntl_signal(SIGCHLD, 'sig_func');
//设置信号处理器
pcntl_signal(SIGTERM, 'sig_func'); $pid = pcntl_fork(); if($pid == -1) {
die('fork error');
} else if ($pid) {
pcntl_wait($status);
} else {
sleep(3);
echo "child \r\n";
sleep(3);
posix_kill(getmypid(), SIGTERM);
exit;
}

父进程等待子进程的退出,子进程等待3秒后输出child,再等待3秒后向自身发送结束程序信号。

例3:
<?php
declare(ticks = 1); //信号处理函数
function sig_func($signo) {
switch($signo) {
case SIGCHLD: {
echo "child SIGCHLD \r\n";
break;
}
/*这里要把处理SIGTERM信号的代码注释掉
case SIGTERM: {
echo "child SIGTERM \r\n";
break;
}*/
default:
//处理所有其他信号
break;
}
} //设置信号处理器
pcntl_signal(SIGCHLD, 'sig_func');
//设置信号处理器,也注释掉
//不然当父进程发向子进程发送SIGTERM信号时,子进程不会退出,还会继续执行
//我们的信号处理函数把SIGTERM给忽略了
//pcntl_signal(SIGTERM, 'sig_func'); $pid = pcntl_fork(); if($pid == -1) {
die('fork error');
} else if ($pid) {
sleep(30); posix_kill($pid, SIGTERM);
} else {
$cnt = 0;
for(;;) {
sleep(3);
echo $cnt, '-';
++$cnt;
}
exit;
}

父进程在等待30秒后,向子进程发送SIGTERM结束程序信号。如果我们设置了SIGTERM信号的处理器,并且在自定义信号处理器中并没有杀死该进程,则该子进程会一直运行下去。

 

pcntl_signal()函数仅仅是注册信号和它的处理方法,真正接收到信号并调用其处理方法的是pcntl_signal_dispatch()函数。

例4:
<?php
//使用ticks需要PHP 4.3.0以上版本
//declare(ticks = 1); function sig_func() {
echo "SIGALRM \r\n";
} //设置信号处理器
pcntl_signal(SIGALRM, 'sig_func'); pcntl_alarm(3);

通过函数pcntl_alarm()3秒后给进程发送SIGALRM信号,但信号处理函数并未调用。

原因是我们注释了declare(ticks = 1);这段代码,而又没有调用pcntl_signal_dispatch()函数。
declare(ticks = 1);表示每执行一条低级指令,就检查一次信号,如果检测到注册的信号,就调用其信号处理器。但是这种处理方式效率很低,建议在代码循环中通过pcntl_signal_dispatch()来处理信号。
<?php
//使用ticks需要PHP 4.3.0以上版本
//declare(ticks = 1); function sig_func() {
echo "SIGALRM \r\n";
} //设置信号处理器
pcntl_signal(SIGALRM, 'sig_func'); pcntl_alarm(3); //因为3秒后pcntl_alarm函数才会给进程发送SIGALRM信号
//所以我们通过sleep函数等待3秒后,调用pcntl_signal_dispatch()来处理信号
sleep(3);
pcntl_signal_dispatch();
pcntl_signal_dispatch()这个函数是PHP5.3以上才支持的,如果你的PHP版本大于5.3,建议使用这个方法调用信号处理器。
5.3以下的版本需要在注册信号之前加上:declare(ticks = 1);
 

php 中的信号处理的更多相关文章

  1. 浅谈Linux中的信号处理机制(二)

    首先谢谢 @小尧弟 这位朋友对我昨天夜里写的一篇<浅谈Linux中的信号处理机制(一)>的指正,之前的题目我用的“浅析”一词,给人一种要剖析内核的感觉.本人自知功力不够,尚且不能对着Lin ...

  2. 如何在Python中加速信号处理

    如何在Python中加速信号处理 This post is the eighth installment of the series of articles on the RAPIDS ecosyst ...

  3. 浅谈Linux中的信号处理机制(三)

    一晃眼,已经到9月底了,都来不及去感慨时间匆匆.最近常常会想明年的今天我将会在那里干着什么样的工作?对未来又是憧憬又是担忧,压力山大.无论如何现在还是踏踏实实的学习吧,能这样安安静静学习的日子也不多了 ...

  4. 浅谈Linux中的信号处理机制(一)

    有好些日子没有写博客了,自己想想还是不要荒废了时间,写点儿东西记录自己的成长还是百利无一害的.今天是9月17号,暑假在某家游戏公司实习了一段时间,做的事情是在Windows上用c++写一些游戏英雄技能 ...

  5. [转] gdb中忽略信号处理

    信号(Signals) 信号是一种软中断,是一种处理异步事件的方法.一般来说,操作系统都支持许多信号.尤其是UNIX,比较重要应用程序一般都会处理信号.UNIX定义了许 多信号,比如SIGINT表示中 ...

  6. Golang中的信号处理

    信号类型 个平台的信号定义或许有些不同.下面列出了POSIX中定义的信号. Linux 使用34-64信号用作实时系统中. 命令 man 7 signal 提供了官方的信号介绍. 在POSIX.1-1 ...

  7. Linux 多线程应用中如何编写安全的信号处理函数

    http://blog.163.com/he_junwei/blog/static/1979376462014021105242552/ http://www.ibm.com/developerwor ...

  8. Linux 多线程应用中如何编写安全的信号处理函数【转】

    转自:https://www.cnblogs.com/virusolf/p/4945642.html http://blog.163.com/he_junwei/blog/static/1979376 ...

  9. Quartus II中的Waring(转)

    1.Found clock-sensitive change during active clock edge at time <time> on register "<n ...

随机推荐

  1. 第3章 文件I/O(2)_文件I/O系统调用及文件描述符

    2. 文件I/O系统调用及文件描述符 2.1 文件I/O系统调用 (1)主要函数 函数 功能 函数 功能 open() 打开文件 read() 读取文件 creat() 创建文件 write() 写入 ...

  2. php 流程控制switch实例

    switch允许对一个标量(表达式)的多个可能结果做选择. 语法: switch (expr) { case result1: statement1 break; case result2: stat ...

  3. Python - Django - App 的概念

    App 方便我们在一个大的项目中,管理实现不同的业务功能 创建 App: 命令行: python manage.py startapp app名 使用 Pycharm 创建: 文件 -> 新建项 ...

  4. django中使用Form组件

    内容: 1.Form组件介绍 2.Form组件常用字段 3.Form组件校验功能 4.Form组件内置正则校验 参考:https://www.cnblogs.com/liwenzhou/p/87478 ...

  5. tornado-输入

    获取输入的信息: *** get_argument get_arguments 兼顾以下两种常用    能从url中获取    ?name=xiaoming    能从body中获取    form表 ...

  6. jQuery id模糊 选择器 批量处理

    $("span[id^='province_']").each(function(index,obj){        $(obj).bind("click", ...

  7. Python 中一个逗号引发的悲剧

    遇到一个 Python 字符串的坑,记录一下.看看下面这些代码 >>> a = [ ... 'foo' ... 'bar', ... 'tree' ... ] >>> ...

  8. css之为文本添加线性渐变和外描边

    css之为文本添加线性渐变和外描边  一.效果: 描边:描边+渐变: 二.描边: api:text-stroke 问题:text-stroke的描边是居中描边,无法直接设置外描边 解决:在before ...

  9. BDE 退出历史 迁移至FireDAC

    BDE组件套TQuery\TTable\TStoreProce结束历时使命. ADO组件套也停止更新, 将来是FireDAC组件套的江湖 Migrating BDE Applications to F ...

  10. c++builder 代码模板 code templates

    c++builder6.0  MENU:Tools>Editor Options>Code Insight>Code templates XE6 c++builder D:\Prog ...