守护进程可php
具体概念可参考c的html
daemon.phpshell
<?php echo 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 SID 10103 10101 10103 10103 10609 10103 10609 10103 10610 10609 10609 10103 10611 10609 10609 10103 10612 10609 10609 10103 [root@hkui ~]# ps --pid 10101 -o pid,ppid,pgid,sid PID PPID PGID SID 10101 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为一个进程组 10103 bash建立的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 SID 10564 1 10564 10564 10565 10564 10564 10564 10566 10564 10564 10564 10567 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