【问题标题】:php cronjob interruptionphp cronjob 中断
【发布时间】:2011-12-29 12:50:21
【问题描述】:

我在 php 中有一个 cronjob,它计算很少的业务规则(例如:净转速、总转速、估计转速等......使用标准偏差和其他数学算法)

这个 cronjob 使用 exec 调用多个 cron 调用 3 个 php 脚本

对于每个调用,我都会在后台启动一个进程并告诉系统作业 x 已启动。例如:

这是我的逻辑

start 
 main cron start - message
  cron sub 1 start - message
  run cron sub 1
  cron sub 1 end - message

  wait until cron sub 1 stop

  process stuff  

  cron sub 2 start - message
  run background cron sub 2 // this will automaticaly send a message when this jobs end

  cron sub 3 start - message
  run background cron sub 3 // this will automaticaly send a message when this jobs end

 main cron end - message

end

我需要解决的是这个

如果有人手动运行作业并取消它 (ctrl+c) 或 cron 中发生了一些不好的事情(致命错误或无法连接到数据库) 或其他任何东西(比如内存不足)

我想停止 cronjob 并告诉它发生了什么以及何时停止,这样我就可以回到原来的位置。

有可能吗?谢谢

【问题讨论】:

    标签: php cron


    【解决方案1】:

    这是您必须尝试/调试的简单代码:

    <?php
    ignore_user_abort(false);
    
    function shutdown() {
      echo "shutdown function\n";
    }
    register_shutdown_function('shutdown');
    
    class shutdown {
      function __construct() {
        echo "shutdown::construct\n";
      }
      function __destruct() {
        echo "shutdown::destruct\n";
      }
    }
    
    $s = new shutdown();
    
    declare(ticks = 1);
    
    function sig_handler($signo) {
    
      switch ($signo) {
        case SIGTERM:
          echo "SIG: handle shutdown tasks\n";
          break;
        case SIGHUP:
          echo "SIG: handle restart tasks\n";
          break;
        case SIGUSR1:
          echo "SIG: Caught SIGUSR1\n";
          break;
        case SIGINT:
          echo "SIG: Caught CTRL+C\n";
          break;
        default:
          echo "SIG: handle all other signals\n";
          break;
      }
      return;
    }
    
    echo "Installing signal handler...\n";
    
    pcntl_signal(SIGTERM, "sig_handler");
    pcntl_signal(SIGHUP,  "sig_handler");
    pcntl_signal(SIGUSR1, "sig_handler");
    pcntl_signal(SIGINT, "sig_handler");
    
    echo "Generating signal SIGTERM to self...\n";
    
    # killing the script using bad memory allocation
    /*
    ini_set('memory_limit', '1K');
    $data = '';
    for($i = 0; $i < 1000; $i++) {
      $data .= str_repeat($i . time(), time());
    }
    */
    
    # simulating CTRL+C
    // for($i = 0; $i < 100000000; $i++) {  } // don't forget to press CTRL+C
    
    echo "Done\n";
    

    如果 cronjob 正常运行,你会得到:

    shutdown::construct
    Installing signal handler...
    Generating signal SIGTERM to self...
    Done
    shutdown function
    shutdown::destruct
    

    如果您遇到致命错误:

    shutdown::construct
    Installing signal handler...
    Generating signal SIGTERM to self...
    PHP Fatal error:  Possible integer overflow in memory allocation (11 * 1321404273 + 1) in /var/www/domain.com/php.php on line 51
    shutdown function
    

    如果你终止进程:

    kill <processid>
    
    shutdown::construct
    Installing signal handler...
    Generating signal SIGTERM to self...
    SIG: handle shutdown tasks
    Done
    shutdown function
    shutdown::destruct
    

    您也可以在每种情况下使用posix_kill(posix_getpid(), &lt;signal you like&gt;);

    了解更多:

    http://php.net/manual/en/function.pcntl-signal.php

    http://en.wikipedia.org/wiki/Signal_%28computing%29

    http://users.actcom.co.il/~choo/lupg/tutorials/signals/signals-programming.html

    【讨论】:

    • 谢谢,我不得不更改您的代码以匹配我的代码,但它可以工作
    【解决方案2】:

    如果这是一个 bash 脚本,您可以像这样捕获 ctrl+c 信号:

    is_borked()
    {
        echo "Somebody set up us the bomb"
        exit
    }
    
    trap is_borked SIGINT
    

    如果您需要某种清理,您可以跟踪(通过变量?)这发生在哪一步。

    【讨论】:

      猜你喜欢
      • 2020-04-12
      • 1970-01-01
      • 2012-01-08
      • 2012-11-16
      • 2023-03-20
      • 1970-01-01
      • 2018-08-14
      • 2012-08-07
      • 2015-11-30
      相关资源
      最近更新 更多