美文网首页
守护线程

守护线程

作者: 苏大发 | 来源:发表于2017-11-02 21:19 被阅读0次

其一

/*
 * php 进程管理
 */
fclose(STDIN);
fclose(STDOUT);
fclose(STDERR);
$STDIN = fopen('/dev/null', 'r');
$STDOUT = fopen('application.log', 'wb');
$STDERR = fopen('error.log', 'wb');
echo '父进程:'.posix_getpid()."\r\n";
$pid = pcntl_fork();
//父进程和子进程都会执行下面代码
echo '创建了子进程:'.$pid . "\r\n";
if ($pid == -1) {
    //错误处理:创建子进程失败时返回-1.
    die('could not fork');
} else if ($pid > 0) {
    //父进程会得到子进程号,所以这里是父进程执行的逻辑
    //pcntl_wait($status); //等待子进程中断,防止子进程成为僵尸进程。
    echo '结束父进程'."\r\n";
    exit(0);
} 
//子进程得到的$pid为0, 所以这里是子进程执行的逻辑。
$sid = posix_setsid();  //Make the current process a session leader
if($sid < 0){
    //-1 创建失败
    exit(1);
}
while(true){
    sleep(1);
    echo '守护进程在运行,时间:'.date('Y-m-d H:i:s')."\r\n";
}

其二

<?php  
  
$pid = pcntl_fork();  
  
if ($pid == -1)  
{  
    throw new Exception('fork子进程失败');  
}  
elseif ($pid > 0)  
{  
    //父进程退出,子进程变成孤儿进程被1号进程收养,进程脱离终端  
    exit(0);  
}  
  
// 最重要的一步,让该进程脱离之前的会话,终端,进程组的控制  
posix_setsid();  
  
// 修改当前进程的工作目录,由于子进程会继承父进程的工作目录,修改工作目录以释放对父进程工作目录的占用。
// 这里重定向了根目录。在后面可以再次重定向指定文件目录  
chdir('/');  
  
/* 
 * 通过上一步,我们创建了一个新的会话组长,进程组长,且脱离了终端,但是会话组长可以申请重新打开一个终端,为了避免 
 * 这种情况,我们再次创建一个子进程,并退出当前进程,这样运行的进程就不再是会话组长。 
 */  
$pid = pcntl_fork();  
if ($pid == -1)  
{  
    throw new Exception('fork子进程失败');  
}  
elseif ($pid > 0)  
{  
    //  再一次退出父进程,子进程成为最终的守护进程  
    exit(0);  
}  
  
// 由于守护进程用不到标准输入输出,关闭标准输入,输出,错误输出描述符  
fclose(STDIN);  
fclose(STDOUT);  
fclose(STDERR);  
  
/* 
 * 处理业务代码 
 */  
  
while(TRUE)  
{  
    file_put_contents('log.txt', time().PHP_EOL, FILE_APPEND);  
    sleep(5);  
}

优化后

<?php  
  
Class Daemon{  
      
    /** 
     * 初始化一个守护进程 
     * @throws Exception 
     */  
    public function init(){  
        //创建一个子进程  
        $pid = pcntl_fork();  
          
        if ($pid == -1) {  
            throw new Exception('fork子进程失败');  
        } elseif ($pid > 0) {  
            //父进程退出,子进程变成孤儿进程被1号进程收养,进程脱离终端  
            exit(0);  
        }  
          
        //创建一个新的会话,脱离终端控制,更改子进程为组长进程  
        $sid = posix_setsid();  
        if ($sid == -1) {  
            throw new Exception('setsid fail');  
        }  
          
        //修改当前进程的工作目录,由于子进程会继承父进程的工作目录,修改工作目录以释放对父进程工作目录的占用。  
        chdir('/');  
          
        /** 
         * 通过上一步,我们创建了一个新的会话组长,进程组长,且脱离了终端,但是会话组长可以申请重新打开一个终端,为了避免 
         * 这种情况,我们再次创建一个子进程,并退出当前进程,这样运行的进程就不再是会话组长。 
         */  
        $pid = pcntl_fork();  
        if ($pid == -1) {  
            throw new Exception('fork子进程失败');  
        } elseif ($pid > 0) {  
            //再一次退出父进程,子进程成为最终的守护进程  
            exit(0);  
        }  
        //由于守护进程用不到标准输入输出,关闭标准输入,输出,错误输出描述符  
        fclose(STDIN);  
        fclose(STDOUT);  
        fclose(STDERR);  
    }  
}  
  
$daemon = new Daemon();  
$daemon->init();  
  
//处理业务代码  
while(true) {  
    file_put_contents('/usr/local/src/log.txt', time().PHP_EOL, FILE_APPEND);  
    sleep(5);  
} 

相关文章

  • 线程知识点复习(一)

    守护线程与非守护线程: java中有两条线程:1.守护线程,2.非守护线程(用户线程)守护线程与main主线程同时...

  • 2018-09-19 守护线程与非守护线程

    什么是守护线程、非守护线程? 什么是守护线程,和main有关。 用户线程(非守护线程): 守护线程,有一个特征,和...

  • Java多线程之<<守护线程>>实战

    定义 什么是守护线程?与守护线程相对应的就是用户线程,守护线程就是守护用户线程,当用户线程全部执行完结束之后,守护...

  • 什么是守护线程

    守护线程定义与守护线程相对应就是用户线程,用户线程可以理解为系统工作的线程,而守护线程守护的就是用户线程。当用户线...

  • Java多线程 - 第二章

    守护线程 Java的线程分为两种:User Thread(用户线程)、DaemonThread(守护线程) 守护线...

  • java线程分类

    守护线程 java中有两类线程,用户线程(User Thread)和守护线程(Daemon Thread)。 守护...

  • java——多线程讲解三

    java多线程的补充:守护线程(后台线程)守护线程:在一个进程中如果只剩下了守护线程,那么守护线程也会死亡。任何一...

  • 守护线程

    守护线程 什么是守护线程? 守护线程:一种特殊的线程,驻守在线程后台,完成系统性的工作,当启动守护线程的线程结束时...

  • 问题:什么是守护线程,使用场景是什么,如何创建守护线程

    问题 什么是守护线程?使用场景是什么?如何创建守护线程? 答案 守护线程 守护线程通常执行一些任务,当所有非守护线...

  • java并发之守护线程

    java中有两种线程,用户线程和守护线程用户线程:主线程停止时,用户线程不会停止守护线程:主线程停止时,守护线程也...

网友评论

      本文标题:守护线程

      本文链接:https://www.haomeiwen.com/subject/whwapxtx.html