AI智能
改变未来

php守护进程创建和简要分析

php守护进程

守护进程可

  • 由系统启动脚本 /etc/rc.local
  • crontab任务,
  • 用户shell
    方式运行

具体概念可参考c的

进程守护化基本步骤

  • 1.创建子进程,终止父进程          (pcntl_fork,exit)
  • 2.在子进程中创建新会话            (posix_setsid)
  • 3.改变工作目录(默认继承了父进程的当前工作目录)  (chdir(\’/\’))
  • 4.重设文件掩码(默认继承了父进程的)   (umask(0) 改变当前的umask为最宽松掩码)
  • 5.关闭文件描述符(默认继承了父进程打开的文件描述符) (fclose  关闭已打开的文件描述符)

daemon.php

<?phpecho posix_getpid().PHP_EOL;$childs = [];$worker_num = 3;//daemon();for ($i = 0; $i < $worker_num; $i++) {    fork();}while (count($childs)) {    if (($exit_id = pcntl_wait($status)) > 0) {        $signo = pcntl_wtermsig($status);        unset($childs[$exit_id]);    }    if (count($childs) < $childs) {        fork();    }}function daemon(){    $pid = pcntl_fork();    if ($pid < 0) die(\"fork err\");    if ($pid == 0) {        if (posix_setsid() <= 0) {            die(\"setsid err!\");        }        if (chdir(\'/\') === false) {            die(\"change dir err\");        }        umask(0);        fclose(STDIN);        fclose(STDOUT);        fclose(STDERR);    } else {        exit();    }}function fork(){    global $childs;    $pid = pcntl_fork();    if ($pid < 0) die(\"fork err\");    if ($pid == 0) {        $child_pid = posix_getpid();        while (true) {            sleep(10);        }    } else {        $parent_pid = posix_getpid();        $childs[$pid] = $pid;    }}

分析

不执行daeon函数时[root@hkui ~]# pstree -p|grep php           |-sshd(3169)-+-sshd(10101)---bash(10103)---php(10609)-+-php(10610)           |            |                                        |-php(10611)           |            |                                        `-php(10612)           [root@hkui ~]# ps --sid 10103 -o pid,ppid,pgid,sid  PID  PPID  PGID   SID10103 10101 10103 1010310609 10103 10609 1010310610 10609 10609 1010310611 10609 10609 1010310612 10609 10609 10103[root@hkui ~]# ps --pid 10101 -o pid,ppid,pgid,sid  PID  PPID  PGID   SID10101  3169 10101 10101[root@hkui ~]# ps --pid 3169 -o pid,ppid,pgid,sid  PID  PPID  PGID   SID 3169     1  3169  3169------------------------------------------------------------------------bash(10103)和它创建的子进程们(10606,10610,10611,10612)属于同一个会话期sid为bash的进程号,所以bash为创建该会话的首进程bash为一个进程组 10103bash创建的php进程为一个进程组 这两个进程组同属一个会话期程序daemon.php运行时创建了进程组10609,它即为组长
执行了daemon()输出10563[root@hkui ~]# pstree -p|grep php           |-php(10564)-+-php(10565)           |            |-php(10566)           |            `-php(10567)[root@hkui ~]# ps --sid 10564 -o pid,ppid,pgid,sid  PID  PPID  PGID   SID10564     1 10564 1056410565 10564 10564 1056410566 10564 10564 1056410567 10564 10564 10564执行了daemon.php后,程序运行起来了,进程id为10563在10563里fork一次,得到子进程10564,父进程10563退出子进程10564里执行setsid后发生了主要的以下三件事    1.10564创建了新的进程组,自己升级为组长    2.10564创建了新的会话组,并成为该会话组的会话首进程    3.10564和控制终端失去联系由于其父进程10563退出,它的父进程变为init进程在10564里fork了3个子进程,继承了10564的组Id,会话Id
赞(0) 打赏
未经允许不得转载:爱站程序员基地 » php守护进程创建和简要分析