版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
守护进程(daemon)是一种生存期长的一种进程。
下面的守护进程代码,参考了workerman源码,进行编写的:
<?php
class Daemon
{
public static $stdoutFile = '/dev/null';
public static $daemonName = 'daemonPHP';
public static function runAll()
{
self::checkEnvCli(); //检查环境
self::daemonize(); //守护进程化
self::chdir(); //改变工作目录
self::closeSTD(); //关闭标准输出、标准错误
self::setProcessTitle(self::$daemonPHP); //设置守护进程的名字
}
protected static function checkEnvCli()
{
if (DIRECTORY_SEPARATOR === '\\') {
exit("must be Linux\n");
}
if (php_sapi_name() != "cli") {
exit("only run in command line mode \n");
}
}
protected static function daemonize()
{
umask(0);
$pid = pcntl_fork();
if (-1 === $pid) {
throw new Exception('fork fail');
} elseif ($pid > 0) {
exit(0);
}
if (-1 === posix_setsid()) {
throw new Exception("setsid fail");
}
// Fork again avoid SVR4 system regain the control of terminal.
$pid = pcntl_fork();
if (-1 === $pid) {
throw new Exception("fork fail");
} elseif (0 !== $pid) {
exit(0);
}
}
protected static function chdir()
{
if (chdir('/')) {
throw new Exception("change dir fail", 1);
}
}
protected static function closeSTD()
{
//定义两个全局变量
global $STDOUT, $STDERR;
$handle = fopen(static::$stdoutFile, "a");
if ($handle) {
unset($handle);
set_error_handler(function () {});
fclose($STDOUT);
fclose($STDERR);
fclose(STDOUT);
fclose(STDERR);
$STDOUT = fopen(static::$stdoutFile, "a");
$STDERR = fopen(static::$stdoutFile, "a");
restore_error_handler();
} else {
throw new Exception('can not open stdoutFile ' . static::$stdoutFile);
}
}
/**
* Set process name.
*
* @param string $title
* @return void
*/
protected static function setProcessTitle($title)
{
set_error_handler(function () {});
// >=php 5.5
if (function_exists('cli_set_process_title')) {
cli_set_process_title($title);
} // Need proctitle when php<=5.5 .
elseif (extension_loaded('proctitle') && function_exists('setproctitle')) {
setproctitle($title);
}
restore_error_handler();
}
}
Daemon::runAll();
//业务代码
while (1) {
file_put_contents('./1.txt', time() . "\n", FILE_APPEND);
sleep(1);
}
参考的链接: