会话就是一个进程组,或是多个进程组的集合
1、使用 posix_setsid()函数设置当前进程为会话首进程
2、当执行php xxx.php 时,默认系统会把当前的进程设置为会话首进程(使用strace查看),所以当前会话首进程不能使用posix_setsid 创建为会话首进程,只能使用子进程调用此函数
3、当调用此函数后,这个进程会变成组长进程,并设置为会话首进程
4、当调用此函数后,该进程不会存在控制终端(可以理解为没有输入、输入设备)
没有setsid的程序
function show()
{
$pid = posix_getpid();
//pid当前进程id ppid 父进程id pgid 会话组id sid 进程的会话id
fprintf(STDOUT,"pid=%d,ppid=%d,pgid=%d,sid=%d\n",$pid,posix_getppid(),posix_getpgid($pid),posix_getsid($pid));
}
$pid = pcntl_fork();
//父子进程都打印
show();
while (1){
;
}
我们通过截图可以看到,18880是18879的子进程,18880和18879的组ID和会话ID是一样的,因为父进程是当前bash进程的子进程,所以继承了父进程的会话ID,而利用pcntl_fork 创建出的子进程则又继承了父进程的信息,所以看到的则是一样的
设置setsid的程序
function show()
{
$pid = posix_getpid();
//pid当前进程id ppid 父进程id pgid 会话组id sid 进程的会话id
fprintf(STDOUT,"pid=%d,ppid=%d,pgid=%d,sid=%d\n",$pid,posix_getppid(),posix_getpgid($pid),posix_getsid($pid));
}
show();
$pid = pcntl_fork();
//让父进程退出,满足技术点第二点
if($pid>0){
exit(200);
}
//创建成功返回会话id,否则返回 -1
$num = posix_setsid();
if($num == -1){
var_dump('创建会话失败');
}else{
var_dump('创建会话成功');
}
show();
while (1){
;
}
通过上面截图可以看到,子进程19578的 pgid和sid 都是19578,也就满足上面提到技术点的第三点,将自己设置为组长进程和会话首进程
通过命令ps -exj
可以看到,设置setsid的这个进程是没有 pts 控制终端的,满足技术点第四点
19578这个进程的父id是1号进程,但并不意味着,这个进程是孤儿进程,而是由一号进程接管的会话首进程
本文为北溟有鱼QAQ原创文章,转载无需和我联系,但请注明来自北溟有鱼QAQ https://www.umdzz.cn