亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 開發 > PHP > 正文

分享PHP守護進程類

2024-05-04 23:41:44
字體:
來源:轉載
供稿:網友
這篇文章主要介紹了PHP守護進程類,守護進程(Daemon)是運行在后臺的一種特殊進程。它獨立于控制終端并且周期性地執行某種任務或等待處理某些發生的事件。守護進程是一種很有用的進程。php也可以實現守護進程的功能,需要的朋友可以參考下
 

用PHP實現的Daemon類??梢栽诜掌魃蠈崿F隊列或者脫離 crontab 的計劃任務。  
使用的時候,繼承于這個類,并重寫 _doTask 方法,通過 main 初始化執行。

<?php class Daemon {   const DLOG_TO_CONSOLE = 1;  const DLOG_NOTICE = 2;  const DLOG_WARNING = 4;  const DLOG_ERROR = 8;  const DLOG_CRITICAL = 16;   const DAPC_PATH = '/tmp/daemon_apc_keys';   /**   * User ID   *   * @var int   */  public $userID = 65534; // nobody   /**   * Group ID   *   * @var integer   */  public $groupID = 65533; // nobody   /**   * Terminate daemon when set identity failure ?   *   * @var bool   * @since 1.0.3   */  public $requireSetIdentity = false;   /**   * Path to PID file   *   * @var string   * @since 1.0.1   */  public $pidFileLocation = '/tmp/daemon.pid';   /**   * processLocation   * 進程信息記錄目錄   *   * @var string   */  public $processLocation = '';   /**   * processHeartLocation   * 進程心跳包文件   *   * @var string   */  public $processHeartLocation = '';   /**   * Home path   *   * @var string   * @since 1.0   */  public $homePath = '/';   /**   * Current process ID   *   * @var int   * @since 1.0   */  protected $_pid = 0;   /**   * Is this process a children   *   * @var boolean   * @since 1.0   */  protected $_isChildren = false;   /**   * Is daemon running   *   * @var boolean   * @since 1.0   */  protected $_isRunning = false;   /**   * Constructor   *   * @return void   */  public function __construct() {     error_reporting(0);    set_time_limit(0);    ob_implicit_flush();     register_shutdown_function(array(&$this, 'releaseDaemon'));  }   /**   * 啟動進程   *   * @return bool   */  public function main() {     $this->_logMessage('Starting daemon');     if (!$this->_daemonize()) {      $this->_logMessage('Could not start daemon', self::DLOG_ERROR);       return false;    }     $this->_logMessage('Running...');     $this->_isRunning = true;     while ($this->_isRunning) {      $this->_doTask();    }     return true;  }   /**   * 停止進程   *   * @return void   */  public function stop() {     $this->_logMessage('Stoping daemon');     $this->_isRunning = false;  }   /**   * Do task   *   * @return void   */  protected function _doTask() {    // override this method  }   /**   * _logMessage   * 記錄日志   *   * @param string 消息   * @param integer 級別   * @return void   */  protected function _logMessage($msg, $level = self::DLOG_NOTICE) {    // override this method  }   /**   * Daemonize   *   * Several rules or characteristics that most daemons possess:   * 1) Check is daemon already running   * 2) Fork child process   * 3) Sets identity   * 4) Make current process a session laeder   * 5) Write process ID to file   * 6) Change home path   * 7) umask(0)   *   * @access private   * @since 1.0   * @return void   */  private function _daemonize() {     ob_end_flush();     if ($this->_isDaemonRunning()) {      // Deamon is already running. Exiting      return false;    }     if (!$this->_fork()) {      // Coudn't fork. Exiting.      return false;    }     if (!$this->_setIdentity() && $this->requireSetIdentity) {      // Required identity set failed. Exiting      return false;    }     if (!posix_setsid()) {      $this->_logMessage('Could not make the current process a session leader', self::DLOG_ERROR);       return false;    }     if (!$fp = fopen($this->pidFileLocation, 'w')) {      $this->_logMessage('Could not write to PID file', self::DLOG_ERROR);      return false;    } else {      fputs($fp, $this->_pid);      fclose($fp);    }     // 寫入監控日志    $this->writeProcess();     chdir($this->homePath);    umask(0);     declare(ticks = 1);     pcntl_signal(SIGCHLD, array(&$this, 'sigHandler'));    pcntl_signal(SIGTERM, array(&$this, 'sigHandler'));    pcntl_signal(SIGUSR1, array(&$this, 'sigHandler'));    pcntl_signal(SIGUSR2, array(&$this, 'sigHandler'));     return true;  }   /**   * Cheks is daemon already running   *   * @return bool   */  private function _isDaemonRunning() {     $oldPid = file_get_contents($this->pidFileLocation);     if ($oldPid !== false && posix_kill(trim($oldPid),0))    {      $this->_logMessage('Daemon already running with PID: '.$oldPid, (self::DLOG_TO_CONSOLE | self::DLOG_ERROR));       return true;    }    else    {      return false;    }  }   /**   * Forks process   *   * @return bool   */  private function _fork() {     $this->_logMessage('Forking...');     $pid = pcntl_fork();     if ($pid == -1) {      // 出錯      $this->_logMessage('Could not fork', self::DLOG_ERROR);       return false;    } elseif ($pid) {      // 父進程      $this->_logMessage('Killing parent');       exit();    } else {      // fork的子進程      $this->_isChildren = true;      $this->_pid = posix_getpid();       return true;    }  }   /**   * Sets identity of a daemon and returns result   *   * @return bool   */  private function _setIdentity() {     if (!posix_setgid($this->groupID) || !posix_setuid($this->userID))    {      $this->_logMessage('Could not set identity', self::DLOG_WARNING);       return false;    }    else    {      return true;    }  }   /**   * Signals handler   *   * @access public   * @since 1.0   * @return void   */  public function sigHandler($sigNo) {     switch ($sigNo)    {      case SIGTERM:  // Shutdown        $this->_logMessage('Shutdown signal');        exit();        break;       case SIGCHLD:  // Halt        $this->_logMessage('Halt signal');        while (pcntl_waitpid(-1, $status, WNOHANG) > 0);        break;      case SIGUSR1:  // User-defined        $this->_logMessage('User-defined signal 1');        $this->_sigHandlerUser1();        break;      case SIGUSR2:  // User-defined        $this->_logMessage('User-defined signal 2');        $this->_sigHandlerUser2();        break;    }  }   /**   * Signals handler: USR1   * 主要用于定時清理每個進程里被緩存的域名dns解析記錄   *   * @return void   */  protected function _sigHandlerUser1() {    apc_clear_cache('user');  }   /**   * Signals handler: USR2   * 用于寫入心跳包文件   *   * @return void   */  protected function _sigHandlerUser2() {     $this->_initProcessLocation();     file_put_contents($this->processHeartLocation, time());     return true;  }   /**   * Releases daemon pid file   * This method is called on exit (destructor like)   *   * @return void   */  public function releaseDaemon() {     if ($this->_isChildren && is_file($this->pidFileLocation)) {      $this->_logMessage('Releasing daemon');       unlink($this->pidFileLocation);    }  }   /**   * writeProcess   * 將當前進程信息寫入監控日志,另外的腳本會掃描監控日志的數據發送信號,如果沒有響應則重啟進程   *   * @return void   */  public function writeProcess() {     // 初始化 proc    $this->_initProcessLocation();     $command = trim(implode(' ', $_SERVER['argv']));     // 指定進程的目錄    $processDir = $this->processLocation . '/' . $this->_pid;    $processCmdFile = $processDir . '/cmd';    $processPwdFile = $processDir . '/pwd';     // 所有進程所在的目錄    if (!is_dir($this->processLocation)) {      mkdir($this->processLocation, 0777);      chmod($processDir, 0777);    }     // 查詢重復的進程記錄    $pDirObject = dir($this->processLocation);    while ($pDirObject && (($pid = $pDirObject->read()) !== false)) {      if ($pid == '.' || $pid == '..' || intval($pid) != $pid) {        continue;      }       $pDir = $this->processLocation . '/' . $pid;      $pCmdFile = $pDir . '/cmd';      $pPwdFile = $pDir . '/pwd';      $pHeartFile = $pDir . '/heart';       // 根據cmd檢查啟動相同參數的進程      if (is_file($pCmdFile) && trim(file_get_contents($pCmdFile)) == $command) {        unlink($pCmdFile);        unlink($pPwdFile);        unlink($pHeartFile);         // 刪目錄有緩存        usleep(1000);         rmdir($pDir);      }    }     // 新進程目錄    if (!is_dir($processDir)) {      mkdir($processDir, 0777);      chmod($processDir, 0777);    }     // 寫入命令參數    file_put_contents($processCmdFile, $command);    file_put_contents($processPwdFile, $_SERVER['PWD']);     // 寫文件有緩存    usleep(1000);     return true;  }   /**   * _initProcessLocation   * 初始化   *   * @return void   */  protected function _initProcessLocation() {     $this->processLocation = ROOT_PATH . '/app/data/proc';    $this->processHeartLocation = $this->processLocation . '/' . $this->_pid . '/heart';  }}


注:相關教程知識閱讀請移步到PHP教程頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
97久久精品人人澡人人爽缅北| 日韩美女视频免费看| 国产丝袜一区二区| 亚洲精品小视频在线观看| 久久久av一区| 日韩欧美亚洲综合| 亚洲视频国产视频| 九九精品在线观看| 亚洲一区二区久久久| 国内久久久精品| 2019中文在线观看| 国产精品综合网站| 国色天香2019中文字幕在线观看| 欧美激情视频网址| 欧美肥老妇视频| 色综合五月天导航| 亚洲人线精品午夜| 欧美性极品xxxx娇小| 亚洲精品久久久久国产| 亚洲在线观看视频网站| 国产精品欧美激情| 欧美日韩视频免费播放| 国产xxx69麻豆国语对白| 欧美韩国理论所午夜片917电影| 日韩免费观看视频| 亚洲永久免费观看| 深夜成人在线观看| 久久99热精品| 欧美乱人伦中文字幕在线| 国产成人精品优优av| 精品久久久久久久久久| 欧美中文字幕在线播放| 一区二区三区美女xx视频| 国产中文欧美精品| 国产激情视频一区| 欧美激情欧美激情在线五月| 97在线观看免费| 黑人巨大精品欧美一区二区免费| 欧美日韩中文字幕在线视频| 日本午夜在线亚洲.国产| 日韩精品在线私人| 欧美日韩免费观看中文| 欧美激情视频一区| 欧美在线性爱视频| 日韩av在线影视| 日韩欧美精品中文字幕| 丝袜情趣国产精品| 日韩在线免费视频观看| 成人激情在线观看| 亚洲国产精品久久久| 精品欧美一区二区三区| 国产午夜精品久久久| 国产日韩精品入口| 一区二区亚洲欧洲国产日韩| 久操成人在线视频| 这里只有精品在线观看| 日韩中文字幕国产精品| 久久综合国产精品台湾中文娱乐网| 精品爽片免费看久久| 欧美精品久久久久a| 日韩欧美999| 国产精品久久久久久久app| 欧美电影第一页| 国产精品三级网站| 欧美日韩激情视频8区| 亚洲福利视频网| 91亚洲精品一区二区| 亚洲一区中文字幕在线观看| 成人久久一区二区| 在线观看视频99| 精品久久久免费| 日韩av在线免费观看一区| 国产精品免费久久久久影院| 欧美午夜激情视频| 有码中文亚洲精品| 精品中文字幕在线观看| 九九热视频这里只有精品| 国产精品爽黄69天堂a| 国产欧美精品久久久| 中文字幕视频一区二区在线有码| 日韩在线观看你懂的| 992tv成人免费影院| 国产精品一区久久久| 亚洲精品一区久久久久久| 国产香蕉一区二区三区在线视频| 国产精品美女主播在线观看纯欲| 日韩一区二区三区国产| 亚洲激情视频在线播放| 国产成人精品国内自产拍免费看| 亚洲mm色国产网站| 久久久久久亚洲精品不卡| 国产mv免费观看入口亚洲| 久久69精品久久久久久国产越南| 欧美激情中文字幕乱码免费| 欧美在线视频导航| 国产精国产精品| 98视频在线噜噜噜国产| 国产视频久久久久| 久久99国产精品久久久久久久久| 国产日韩视频在线观看| 欧美高清一级大片| 亚洲日韩中文字幕在线播放| 久久国产精品首页| 中文字幕亚洲自拍| 国产在线观看精品| 国产亚洲激情在线| 亚洲精品美女视频| 日韩中文在线中文网三级| 国产精品爽爽爽爽爽爽在线观看| 国产精品偷伦视频免费观看国产| 精品免费在线观看| 亚洲一区二区三区四区视频| 欧美日韩国产999| 久久久国产91| 国产精品中文字幕在线| 日韩av手机在线观看| 国产97色在线| 国产精品免费观看在线| 日韩av免费在线观看| 日韩在线观看精品| 亚洲免费人成在线视频观看| 91久久中文字幕| 亚洲国产又黄又爽女人高潮的| 91网在线免费观看| 性色av一区二区三区| 韩国三级日本三级少妇99| 欧美在线视频在线播放完整版免费观看| 亚洲欧美国产精品| 国产精品女主播视频| 永久免费看mv网站入口亚洲| 亚洲日韩中文字幕| 欧美亚洲另类在线| 国产精品91在线| 热re91久久精品国99热蜜臀| 国产日韩欧美影视| 欧美最猛性xxxxx亚洲精品| 久久久久久中文字幕| 国产日韩av在线| 欧美中文字幕视频在线观看| 亚洲成人久久电影| 国产精品69精品一区二区三区| 久久香蕉国产线看观看av| 亚洲精品一二区| 欧美大胆a视频| 精品久久久国产| 成人免费在线视频网址| 国产在线精品播放| 亚洲最大av网站| 中文字幕亚洲综合久久筱田步美| 亚洲最大福利视频| 欧美亚洲第一页| 国产精品视频在线播放| 亚洲天堂网在线观看| www.xxxx欧美| 亚洲精品在线不卡| www.久久色.com| 欧美性少妇18aaaa视频| 精品一区精品二区| 久久免费视频在线| 亚洲a中文字幕| 成人精品一区二区三区电影黑人| 91av在线播放| 91av在线精品| 久久影院免费观看|