linux php 进程进阶(七)sid(会话)

bash进程与终端概念

会话基本概念

说起会话,我们经常登录到linux系统, linux是一个多用户多任务的分时操作系统,必须要支持多个用户同时登陆同一个操作系统,当一个用户登陆一次终端时就会产生一个会话,执行各种各样的程序,这都牵涉到会话。
会话是基于连接的。会话的源头,就是用户与系统之间连接的启用。

会话:会话(session)是一个或多个进程组的集合。

在这里插入图片描述

会话首进程:一个会话里是有很多进程的,第一个被创建出来的进程就是会话首进程,会话首进程(session leader)是指创建会话的进程,其进程ID会成为会话ID,会话中的所有进程都具有相同的会话标识符。

每个会话有一个会话首进程,即创建会话的进程,建立与终端连接的就是这个会话首进程,也被称为控制进程。一个会话可以包括多个进程组, 这些进程组可被分为一个前台进程组和一个或多个后台进程组。为什么要这么分呢?前台进程组是指需要与终端进行交互的进程组(只能有一个)

使用会话最多的是支持任务控制的shell,由shell创建的所有进程组与shell自身隶属于同一会话,shell是此会话的会话首进程。

打开控制终端会致使会话首进程成为终端的控制进程。一旦断开了与终端的连接(比如,关闭了终端窗口),控制进程将会收到SIGHUP信号。

创建一个会话

  1. posix_setsid() 使当前进程成为session leader(会话首进程)
  2. 不能使用组长进程调用 posix_setsid 函数,要是硬要调用,就会报错。
    我们可以编写代码测试一下
<?php
# 设置当前进程为会话首进程
$sid = posix_setsid();
#调用 posix_setsid() 函数错误会返回 -1
if(-1 === $sid){
        print("sid error".PHP_EOL);

}
# 获取当前进程进程pid
$pid = posix_getpid();
#打印当前进程pid,调用posix_setsid函数后的会话id,组id,当前进程所属的会话id
fprintf(STDOUT,"pid=%d,sid=%d,pgid=%d,getsid=%d\n",$pid,$sid,posix_getpgid($pid),posix_getsid($pid));
# 方便查看进程关系
while(true)
{
        #睡眠
        sleep(2);
}

在这里插入图片描述
先执行demo1.php 后我们在另一个终端执行 pstree -ap 查看进程关系,对比两张图发现,执行demo1.php 得到当前进程id为 12968 ,又因为demo1.php 是在bash 进程执行所以会话id 为 1526,组id和进程id相同表示当前进程就是进程组长,所以就不难理解为什么调用posix_setsid 函数返回 -1 了。

  1. 我们一般先创建一个子进程,让父进程exit 退出,由子进程调用 posix_setsid 函数
    我们也可以编写代码测试一下
<?php
#设置会话前先打印做对比
#打印当前进程pid,组id,当前进程所属的会话id,当前进程父进程ppid
$pid = posix_getpid();
fprintf(STDOUT,"pid=%d,pgid=%d,getsid=%d,ppid=%d\n",$pid,posix_getpgid($pid),posix_getsid($pid),posix_getppid());

# fork 子进程
$pid = pcntl_fork();
if($pid > 0){
	exit(0);
}
# 设置当前进程为会话首进程
$sid = posix_setsid();
#调用 posix_setsid() 函数错误会返回 -1
if(-1 === $sid){
        print("sid error".PHP_EOL);

}else{
	print("会话首进程设置成功".PHP_EOL);
}
# 获取当前进程进程pid
$pid = posix_getpid();
#打印当前进程pid,调用posix_setsid函数后的会话id,组id,当前进程父进程ppid
fprintf(STDOUT,"pid=%d,sid=%d,pgid=%d,getsid=%d\n",$pid,$sid,posix_getpgid($pid),posix_getppid());
# 方便查看进程关系
while(true)
{
        #睡眠
        sleep(2);
}

在这里插入图片描述
先执行demo2.php 后我们在另一个终端执行 pstree -ap|grep -E "demo2.php|bash|systemd|sshd" 查看进程关系,对比两张图发现,demo2.php 在创建子进程后父进程退出,留下子进程,子进程必不会是进程组长,故而可以调用 posix_setsid 函数设置自己为会话首进程,需要特别注意的是,子进程设置自己为会话首进程后终端连接就断开了,也就是说这时候你在终端输入什么 ctrl+c 对demo2.php 是没有作用的,它已经彻底转为后台进程了

  1. 调用 posix_setsid 函数之后,该进程会变成 组长进程,同时也会变成会话首进程
  2. 同时该进程没有控制终端(没有控制终端可以理解为,进程没有连接显示器,没有连接键盘)它没有控制终端了,你在终端里输入任何数据都没有反应
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值