1. 什么是信号

信号(Signal)是事件发生时对进程的通知机制,可用于进程间通信。

2. 常用信号

信号类型有很多种,这里只记录几个我常用的:

  1. <?
  2. // 退出信号。当进程运行时,手动键入ctrl + c,就是发送 `kill -2 pid`
  3. define ('SIGINT', 2);
  4. // 终止信号。强制退出,不能被阻塞、处理或忽略
  5. define ('SIGKILL', 9);
  6. // 忽略信号。当子进程退出或终止时通知父进程
  7. define ('SIGCHLD', 17);

3. PHP信号相关函数

  1. 安装扩展pcntl与扩展posix。
  2. declare(ticks=N) :PHP监听代码运行,每运行N行低级代码,就会触发 tick 的监听回调处理函数 register_tick_function() 。用法如下: ```php <?php declare(ticks=1);

function tick_handler($arg) { echo $arg . “ tick_handler() called\n”; }

register_tick_function(‘tick_handler’, ‘what’);

$a = 1;

if ($a > 0) { $a += 2; print($a); }

  1. 3. `pcntl_signal()` :监听处理信号的变化,做出指定反应。用法如下:
  2. ```php
  3. <?php
  4. declare(ticks=1);
  5. pcntl_signal(SIGINT, function(){
  6. exit("Get signal SIGINT and exit\n");
  7. });
  8. echo "Ctl + c or run cmd : kill -SIGINT " . posix_getpid(). "\n" ;
  9. while(1){
  10. $num = 1;
  11. }
  1. posix_kill() :向进程发送一个信号。用法如下:

    1. <?php
    2. posix_kill($pid, SIGINT);
  2. pcntl_signal_dispatch() :调用等待信号的处理器,与第3点作用有微妙的变化。用法如下: ```php <?php echo “安装信号处理器…\n”; pcntl_signal(SIGHUP, function () { echo “信号处理器被调用\n”; });

echo “为自己生成SIGHUP信号…\n”; posix_kill(posix_getpid(), SIGHUP);

echo “分发…\n”; pcntl_signal_dispatch();

echo “完成\n”;

  1. 6. `pcntl_async_signals()` :启用/禁用异步信号处理或返回旧设置(PHP7.1才支持)。用法如下:
  2. ```php
  3. <?php
  4. pcntl_async_signals(true);
  5. pcntl_signal(SIGHUP, function () {
  6. echo "信号处理器被调用\n";
  7. });
  8. posix_kill(posix_getpid(), SIGHUP);
  1. pcntl_fork():在当前进程当前位置产生分支(子进程)。(fork创建一个子进程,父进程和子进程都从fork的位置开始向下继续执行,不同的是父进程执行过程中,得到的fork返回值为子进程号,而子进程得到的是0)。用法如下:
    1. <?php
    2. echo "This is test.php\n";
    3. $pid = pcntl_fork();
    4. echo "more\n";
    5. //父进程和子进程都会执行下面代码
    6. if ($pid) {
    7. //父进程会得到子进程号,所以这里是父进程执行的逻辑
    8. echo "i am father\n";
    9. pcntl_wait($status); //等待子进程中断,防止子进程成为僵尸进程。
    10. } else {
    11. //子进程得到的$pid为0, 所以这里是子进程执行的逻辑。
    12. echo "i am child\n";
    13. }