转自:http://shake863.javaeye.com/blog/187085

 

 

将阐述Linux内核中的如下几个概念 
1) 进程组 
2) 会话 
3) 控制终端 

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


进程只能将自身和其子进程设置为进程组 id. 
某个子进程调用 exec 函数之后, 就不能再将该子进程的 id 作为进程组 id. 
=============================================================================== 

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

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

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

 

        总的来说,由于 Linux 是一个多用户系统,同一时刻,系统中运行有属于不同用户的多个进程。那么,当处于某个终端上的用户按下了 Ctrl+C 键时(产生 SIGINT 信号),系统如何知道将该信号发送到哪个进程,从而不影响由其他终端上的用户运行的进程呢?

Linux 内核通过维护会话和进程组而管理多用户进程。如下图所示,每个进程是一个进程组的成员,而每个进程组又是某个会话的成员。一般而言,当用户在某个终端上登录时,一个新的会话就开始了。进程组由组中的领头进程标识,领头进程的进程标识符就是进程组的组标识符。类似地,每个会话也对应有一个领头进程。

        同一会话中的进程通过该会话的领头进程和一个终端相连,该终端作为这个会话的控制终端。一个会话只能有一个控制终端,而一个控制终端只能控制一个会话。用户通过控制终端,可以向该控制终端所控制的会话中的进程发送键盘信号。

        同一会话中只能有一个前台进程组,属于前台进程组的进程可从控制终端获得输入,而其他进程均是后台进程,可能分属于不同的后台进程组。

Linux-会话-进程组关系

 


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

 

 

 

 

3.  关于进程,进程组,会话的一些理解

转自:http://linux.chinaunix.net/bbs/viewthread.php?tid=766191

 

 

(1)进程必定属于一个进程组,也只能属于一个进程组。
     一个进程组中可以包含多个进程。
     进程组的生命周期从被创建开始,到其内所有进程终止或离开该组。

     获取当前进程所在进程组ID使用函数getpgrp
     创建或加入其他组使用函数setpgid

(2)假设条件:pid1进程属于pgid1进程组;pid2属于pgid2进程组,并且是pgid2进程组组长;另有进程组pgid3,

     在pid1进程中调用setpgid(pid2,pgid3);
  
     a)当pid2和pgid3都>0且不相等时
        功能:将pid2进程加入到pgid3组。此时pid2进程脱离pgid2进程组,进入pgid3进程组。
     b)当pid2和pgid3都>0且相等时
        功能:pid2进程创建新进程组,成为新进程组长(pgid3=pid2)。
     c)当pid2==0,pgid>0时
        功能:将调用进程pid1加入到pgid3中。此时pid1脱离pgid1,进入pgid3。
     d)当pid2>0,pgid==0时
        功能:将pid2加入到调用进程所在的pgid1进程组。此时pid2脱离pgid2,进入pgid1。
     e)当pid2和pgid3都==0时,返回错误。

(3)一次登录就形成一次会话,会话组长即创建会话的进程。
     只有不是进程组长的进程才能创建新会话。

(4)如果pid1进程属于pgid1进程组,且不是组长,属于会话sid1。
     在pid1进程中调用setsid();
     功能:pid1进程脱离pgid1进程组,创建一个新的会话sid2(sid2没有控制终端),pid1进程加入到pgid2组(pgid2==pid1)。

 

 

GitHub 加速计划 / li / linux-dash
10.39 K
1.2 K
下载
A beautiful web dashboard for Linux
最近提交(Master分支:2 个月前 )
186a802e added ecosystem file for PM2 4 年前
5def40a3 Add host customization support for the NodeJS version 4 年前
Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐