将阐述Linux内核中的如下几个概念 
1) 进程组 
2) 会话 
3) 控制终端 
前面的概念来源于前人,我只是站在前人的肩膀上结合内核中的实现加深概念理解。

1.概念:

a)进程组 
Shell 上的一条命令行形成一个进程组 
每个进程属于一个进程组 
每个进程组有一个领头进程 
进程组的生命周期到组中最后一个进程终止, 或加入其他进程组为止 
getpgrp: 获得进程组 id, 即领头进程的 pid 
setpgid: 加入进程组和建立新的进程组 
前台进程组和后台进程组

=============================================================================== 
#include <unistd.h>

int setpgid (pid_t pid, pid_t pgid); 
pid_t getpgid (pid_t pid); 
int setpgrp (void); 
pid_t getpgrp (void); 
------------------------------------------------------------------------------- 
进程只能将自身和其子进程设置为进程组 id. 
某个子进程调用 exec 函数之后, 就不能再将该子进程的 id 作为进程组 id. 
===============================================================================

b)会话 
一次登录形成一个会话 
一个会话可包含多个进程组, 但只能有一个前台进程组. 
setsid 可建立一个新的会话 
=============================================================================== 
#include <unistd.h>

pid_t setsid(void); 
------------------------------------------------------------------------------- 
如果调用进程不是进程组的领头进程, 该函数才能建立新的会话. 
调用 setsid 之后, 进程成为新会话的领头进程. 
进程成为新进程组的领头进程. 
进程失去控制终端 
===============================================================================

c)控制终端 
会话的领头进程打开一个终端之后, 该终端就成为该会话的控制终端 (SVR4/Linux) 
与控制终端建立连接的会话领头进程称为控制进程 (session leader) 
一个会话只能有一个控制终端 
产生在控制终端上的输入和信号将发送给会话的前台进程组中的所有进程 
终端上的连接断开时 (比如网络断开或 Modem 断开), 挂起信号将发送到控制进程(session leader)

2. Linux中的实现举例,用以验证上述规则:

asmlinkage long sys_getpgid(pid_t pid) 

if (!pid) { 
return current->pgrp; 
} else { 
int retval; 
struct task_struct *p;

read_lock(&tasklist_lock); 
p = find_task_by_pid(pid);

retval = -ESRCH; 
if (p) 
retval = p->pgrp; 
read_unlock(&tasklist_lock); 
return retval; 

}

/* 
* This needs some heavy checking ... 
* I just haven't the stomach for it. I also don't fully 
* understand sessions/pgrp etc. Let somebody who does explain it. 

* OK, I think I have the protection semantics right.... this is really 
* only important on a multi-user system anyway, to make sure one user 
* can't send a signal to a process owned by another. -TYT, 12/12/91 

* Auch. Had to add the 'did_exec' flag to conform completely to POSIX. 
* LBT 04.03.94 
*/

asmlinkage long sys_setpgid(pid_t pid, pid_t pgid) 

struct task_struct * p; 
int err = -EINVAL;

if (!pid) 
pid = current->pid; 
if (!pgid) 
pgid = pid; 
if (pgid < 0) 
return -EINVAL;

/* From this point forward we keep holding onto the tasklist lock 
* so that our parent does not change from under us. -DaveM 
*/ 
read_lock(&tasklist_lock);

/*第一前提: 先要验证要设定的进程是否存在,不存在的话不能做事*/ 
err = -ESRCH; 
p = find_task_by_pid(pid); 
if (!p) 
goto out;

/* 第二前提: 先要检查做这个操作的权限: 
当前进程只能将自身和其子进程设置为进程组id,并且 
当前进程和其子进程必须属于同一次会话 
(同组的进程一定属于同一次会话) 
*/ 
if (p->p_pptr == current || p->p_opptr == current) 

err = -EPERM;

/*如果不属于同一次会话(同一次控制台),不可以*/ 
if (p->session != current->session) 
goto out; 
err = -EACCES;

/*某个子进程调用 exec 函数之后, 就不能再将该子进程的 id 作为进程组 id*/ 
if (p->did_exec) 
goto out; 

else if (p != current) 
goto out;

err = -EPERM;

/*boolean value for session group leader */ 
/*如果是一次会话的leader,也不可以 
注意进程组的首领进程也是可以改变组id的*/ 
if (p->leader) 
goto out;

/*好!几个前提条件全满足了,要做正事了: 
但是是不是组号的合法性还没有验证?见后话!*/

/*要设进程号不是要设定的组号,如果是,直接设,因为这 
意味着是增加了以自己的pid作为新的组号的进程组,这个 
进程也将成为新进程组的首领进程,所以在此根本不用比较 
会话号,自己对自己肯定是同一次会话.如果条件不满足,则 
要做这些判断*/ 
if (pgid != pid) 

struct task_struct * tmp; 
for_each_task (tmp) 

/*能不能找到一个进程,组号正好是要设定的组号, 
并且和要设定的进程属于同一个控制台(同一个会话) 
找到才可以设定,其实这里就是要判定组号的合法性, 
即必须是一个已经存在的组,而且和当前同一次会话才 
可以操作,这个也不能忘记,其实就是说:同组的进程 
一定属于同一次会话*/ 
if (tmp->pgrp == pgid && 
tmp->session == current->session) 
goto ok_pgid; 
}

goto out; 
}

ok_pgid: 
p->pgrp = pgid; 
err = 0; 
out: 
/* All paths lead to here, thus we are safe. -DaveM */ 
read_unlock(&tasklist_lock); 
return err; 
}

asmlinkage long sys_getsid(pid_t pid) 

if (!pid) { 
return current->session; 
} else { 
int retval; 
struct task_struct *p;

read_lock(&tasklist_lock); 
p = find_task_by_pid(pid);

retval = -ESRCH; 
if(p) 
retval = p->session; 
read_unlock(&tasklist_lock); 
return retval; 

}

asmlinkage long sys_setsid(void) 

struct task_struct * p; 
int err = -EPERM;

read_lock(&tasklist_lock); 
for_each_task(p) 

/*如果当前进程是一个进程组的首领进程, 
则不能建立一个新的会话*/ 
if (p->pgrp == current->pid) 
goto out; 
}

/*将新创建会话的leader设定为创建者就是当前进程*/ 
current->leader = 1;

/*清楚看见一个新的进程组诞生了 
当前进程成为新进程组的首领进程 
新会话的id 是当前进程号,也是新会话的leader 
*/ 
current->session = current->pgrp = current->pid;

/*当前进程失去控制终端*/ 
current->tty = NULL; 
current->tty_old_pgrp = 0; 
err = current->pgrp; 
out: 
read_unlock(&tasklist_lock); 
return err;

}

Linux中的进程组及会话相关推荐

  1. Linux内核中的进程组及会话

    Linux内核中的进程组及会话 将阐述Linux内核中的如下几个概念 1) 进程组 2) 会话 3) 控制终端 前面的概念来源于前人,我只是站在前人的肩膀上结合内核中的实现加深概念理解. 1.概念: ...

  2. linux操作系统之进程组及会话

    (1)进程组(作业):代表一个或多个进程的集合. 1)父进程创建子进程时,默认子进程与父进程属于同一进程组,进程组id==第一个进程id(组长id,父进程id). 2)使用kill -SIGKILL ...

  3. linux守护进程写法_搞懂进程组、会话、控制终端关系,才能明白守护进程如何创建...

    守护进程 概念: 守护进程,也就是通常所说的Daemon进程,是Linux中的后台服务进程.周期性的执行某种任务或等待处理某些发生的事件. Linux系统有很多守护进程,大多数服务都是用守护进程实现的 ...

  4. Linux内核进程,线程,进程组,会话组织模型以及进程管理

    Linux 内核创世与创生 Linux宇宙诞生之时,创建了三个重要进程,三个进程的PID分别为0,1,2. 做一个不太恰当的比喻,你可以现象成组件一个创业团队,第一步需要找到CEO,CTO,CFO,有 ...

  5. 一文读懂Linux进程、进程组、会话、僵尸

    作者简介 herongwei,北交硕士毕业,现就职于搜狗公司,后端开发工程师.从事 C++,Golang ,Linux 后端开发. 追求技术,热爱编程与分享,希望能和大家多多交流学习~ 座右铭:    ...

  6. ora03135连接失去联系 进程id 0_进程组、会话、控制终端概念,如何创建守护进程?...

    守护进程 概念: 守护进程,也就是通常所说的Daemon进程,是Linux中的后台服务进程.周期性的执行某种任务或等待处理某些发生的事件. Linux系统有很多守护进程,大多数服务都是用守护进程实现的 ...

  7. 进程 、进程组、会话、控制终端之间的关系

    一个进程组可以包含多个进程 进程组中的这些进程之间不是孤立的,他们彼此之间或者存在者父子.兄弟关系,或者在功能有相近的联系. 那linux为什么要有进程组呢?其实提供进程组就是方便管理这些进程.假设要 ...

  8. 搞懂进程组、会话、控制终端关系,才能明白守护进程干嘛的?

    守护进程 概念: 守护进程,也就是通常所说的Daemon进程,是Linux中的后台服务进程.周期性的执行某种任务或等待处理某些发生的事件. Linux系统有很多守护进程,大多数服务都是用守护进程实现的 ...

  9. 得到进程id_搞懂进程组、会话、控制终端关系,才能明白守护进程干嘛的?

    守护进程 概念: 守护进程,也就是通常所说的Daemon进程,是Linux中的后台服务进程.周期性的执行某种任务或等待处理某些发生的事件. Linux系统有很多守护进程,大多数服务都是用守护进程实现的 ...

最新文章

  1. 安装composer出现链接补上的问题
  2. Ansible自动化运维应用场景分析
  3. 浏览器title中的小图标0927 0928
  4. Mapper.xml映射文件---Mybatis学习笔记(八)
  5. tomcat 虚拟路径 与 虚拟主机配置
  6. Linux中常见的环境变量笔记
  7. stm32串口空闲中断接收不定长数据
  8. SQL SERVER的SID和表的所有权问题
  9. python3爬取青年文摘999篇精选文章
  10. python皮卡丘编程代码_儿童Python代码编程库Pygame Zero介绍
  11. 《高翔视觉slam十四讲》学习笔记 第三讲 三维空间刚体运动
  12. SpringMVC (三)处理器映射器的配置和AbstractController的使用
  13. Java 设计简单班级管理系统
  14. linux tar 绝对路径,tar打包使用绝对路径详解
  15. (十三)ATP应用测试平台——springboot集成kafka案例实战
  16. 李彦宏“泼水门”:舆论的狂欢,还是魏则西的葬歌?
  17. 扁平化风格pike admin后台模板
  18. C# 中的委托和事件[转自张子扬]
  19. 基于单片机的交通灯设计
  20. mybatis-plus生成java代码

热门文章

  1. 洛谷.4383.[八省联考2018]林克卡特树lct(树形DP 带权二分)
  2. git 使用详解(3)—— 最基本命令 + .gitignore 文件
  3. javase(Properties集合及学生对象信息录入文本中案例)
  4. Node.js项目目录介绍
  5. 仿照微信的效果,实现了一个支持多选、选原图和视频的图片选择器,适配了iOS6-10系统,3行代码即可集成....
  6. 定制kali linux
  7. go:系统参数or函数--未完
  8. xml文件格式例如以下
  9. linux命令管理GPT分区,Linux磁盘管理GPT分区教程
  10. OpenGL之利用模型视图矩阵和投影矩阵让球体自动旋转