Skip to content

Create a daemon with Qpm Process

Qing Zhao edited this page Jun 7, 2016 · 7 revisions

In multitasking computer operating systems, a daemon is a program that runs as a background process, rather than being under the direct control of an interactive user.

The daemon which is programed in PHP always run in CLI mode. It’s very different from the CGI mode. In CGI mode, a life cycle of a script is just a HTTP request, it’s a short time. But the daemons, they often run and have to run a long time.

They often run in a infinite loop like bellows.

<?php
while(true) {
  file_put_contents('foo.log', date('Y-m-d H:i:s')."\n", FILE_APPEND);
  sleep(10);
};
?>

In that example, a time info would be appended to foo.log per every 10 seconds. In the CGI mode, the process would be affected by the max time limitation, that is set in php.ini or the configuration of HTTP server. But in the CLI mode, process would keep running until a termination signal is received.

In a Unix environment, the parent process of a daemon is often, but not always, the init process. A daemon is usually either created by a process forking a child process and then immediately exiting, thus causing init to adopt the child process, or by the init process directly launching the daemon. In addition, a daemon launched by forking and exiting typically must perform other operations, such as dissociating the process from any controlling terminal (tty).

A common solution contains following steps:

  1. Start the process.
  2. Fork a child process.
  3. Let the child run in the background. (posix_setsid())
  4. The parent exits, but the child leaves alone in the background.

A implementor with QPM looks like following(or see the example script in daemon.php).

 use Comos\Qpm\Process\Process;

 //define the main working process.
 function work() {
      while(true) {
        file_put_contents(__FILE__.'.log', date('Y-m-d H:i:s')."\n", FILE_APPEND);
        sleep(10);
      };
 }

 //Start a child by forking
 Process::fork(
      function() {
        //The child send itself to the background
        Process::current()->toBackground();
        work();
      }
 );
Clone this wiki locally