PHP Daemon Class

Source: Internet
Author: User
Tags usleep
The PHP daemon class, the daemon (Daemon) is a special process that runs in the background. It is independent of the control terminal and periodically performs some sort of task or waits to handle certain occurrences. Daemons are a very useful process. PHP can also implement the Daemon function, the need for friends can refer to the following

The daemon class implemented in PHP. You can implement a queue on a server or a scheduled task that is out of crontab.
When used, it inherits from this class and overrides the _dotask method, which is executed through main initialization.

 _logmessage (' starting daemon ');       if (! $this->_daemonize ()) {$this->_logmessage (' Could not start daemon ', self::D log_error);    return false;     } $this->_logmessage (' Running ... ');     $this->_isrunning = true;    while ($this->_isrunning) {$this->_dotask ();  } return true;     }/** * Stops the process * * @return void */Public Function Stop () {$this->_logmessage (' stoping daemon ');  $this->_isrunning = false; }/** * Do task * * @return void */protected function _dotask () {//override this method}/** * _log Message * Logging * * @param string message * @param integer level * @return void */protected function _logmessage ($msg  , $level = self::D log_notice) {//override this method}/** * daemonize * * Several rules or characteristics That most daemons possess: * 1) Check was daemon already running * 2) Fork child process * 3) sets identity * 4) M Ake current Process a session Laeder *5) Write Process ID to file * 6) Change Home path * 7) umask (0) * * @access Private * @since 1.0 * @return Voi     d */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::D log_       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);     }//write to the monitoring log $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::D log_to_console | self::D log_error));    return true;    } else {return false; }}/** * Forks process * * @return BOOL */Private Function _fork () {$this->_logmessage (' forking ... ')     ;     $pid = Pcntl_fork ();       if ($pid = =-1) {//Error $this->_logmessage (' Could not fork ', self::D log_error);    return false; } elseif ($pid) {//parent process $this->_LOGMESSAGE (' Killing parent ');    Exit ();      } else {//fork of child process $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::D log_warning);    return false;    } else {return true; }}/** * Signals handler * * @access Public * @since 1.0 * @return void */Public function Sighandler ($si        GNo) {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 * is primarily used to periodically clean up DNS resolution records for cached domain names in each process * * @return void */protected function _sighand  LerUser1 () {apc_clear_cache (' user '); }/** * Signals HANDLER:USR2 * For writing heartbeat package file * * @return void */protected function _sighandleruser2 () {$th     Is->_initprocesslocation ();     File_put_contents ($this->processheartlocation, Time ());  return true;  }/** * Releases daemon pid file * This method was 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 * Writes the current process information to the monitoring log, the other script scans the data sending signal of the monitoring log and restarts the process if there is no response * * @return void */Public Function writeprocess () {//Initialize proc $this->_initprocesslocation ();     $command = Trim (implode (' ', $_server[' argv ')); Specifies the directory of the process $processDir = $this->processlocation. '/' .    $this->_pid; $processCmdFile = $processDir.    '/cmd '; $processPwdFile = $processDir.     '/pwd ';      The directory where all processes are located if (!is_dir ($this->processlocation)) {mkdir ($this->processlocation, 0777);    chmod ($processDir, 0777);    }//Query duplicate process record $pDirObject = Dir ($this->processlocation); while ($pDirObject && ($pid = $pDirObject->read ())!== false) {if ($pid = = '. ' | | $pid = = ' ... ' | | intva      L ($pid)! = $pid) {continue; } $pDir = $this->processlocation. '/' .      $pid; $pCmdFile = $pDir.      '/cmd '; $pPwdFile = $pDir.      '/pwd '; $pHeartFile = $pDir.       '/heart '; The process of starting the same parameter according to the CMD check if (Is_file ($pCmdFile) && trim (file_get_contents ($pCmdFile)) = = $command) {unlink  ($pCmdFile);      Unlink ($pPwdFile);         Unlink ($pHeartFile);         Delete Directory has cache usleep (1000);      RmDir ($pDir);      }}//New process directory if (!is_dir ($processDir)) {mkdir ($processDir, 0777);    chmod ($processDir, 0777);    }//write command parameter file_put_contents ($processCmdFile, $command);     File_put_contents ($processPwdFile, $_server[' PWD ');     Write files have cache usleep (1000);  return true; }/** * _initprocesslocation * Initialize * * @return void */protected function _initprocesslocation () {$this- >processlocation = Root_path.    '/app/data/proc '; $this->processheartlocation = $this->processlocation. '/' . $this->_pid.  '/heart '; }}
  • Related Article

    Contact Us

    The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

    If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

    A Free Trial That Lets You Build Big!

    Start building with 50+ products and up to 12 months usage for Elastic Compute Service

    • Sales Support

      1 on 1 presale consultation

    • After-Sales Support

      24/7 Technical Support 6 Free Tickets per Quarter Faster Response

    • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.