分享php守护进程类,分享php守护进程用php实现的daemon类。可以在服务器上实现队列或者脱离 crontab 的计划任务。  
使用的时候,继承于这个类,并重写 _dotask 方法,通过 main 初始化执行。
_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守护进程 加linux命令nohup实现任务每秒执行一次php程序级守护进程的实现与优化的使用概述php实现多进程并行操作的详解(可做守护进程)shell脚本作为保证php脚本不挂掉的守护进程实例分享php高级编程实例:编写守护进程php守护进程实例php将进程作为守护进程的方法php扩展程序实现守护进程如何写php守护进程(daemon)
http://www.bkjia.com/phpjc/1086642.htmlwww.bkjia.comtruehttp://www.bkjia.com/phpjc/1086642.htmltecharticle分享php守护进程类,分享php守护进程 用php实现的daemon类。可以在服务器上实现队列或者脱离 crontab 的计划任务。 使用的时候,继承于这个...
   
 
   