php实现守护进程

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/mrtwenty/article/details/99311711

守护进程(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);
}

参考的链接:

PHP实现daemon

workerman

猜你喜欢

转载自blog.csdn.net/mrtwenty/article/details/99311711