会话
会话是一个或多个进程组的集合。
进程组中的进程通常是由shell 管道放进去的。上图所示可能是由如下命令建立起来的:
proc1 | proc2 &
proc3 | proc4 | proc5
通过调用setsid函数将进程连接到一个新的会话里。
#include <unistd.h> pid_t setsid(void); |
Returns: process group ID if OK, 1 on error |
如果调用函数的进程不是进程组长,这个函数建立一个新会话。这时会有三件事发生:
- 该进程会变成新会话的会话长(session leader)。(会话长建立会话)这时该进程是新会话中唯一的进程。
- 该进程会变成新进程组的进程组长(process group leader)。新进程组ID是该进程的进程ID。
- 该进程没有控制终端。如果进程在调用setsid之前有控制终端,那么关联也会被破坏。(if the process had a controlling terminal before calling setsid, that association is broken)
如果调用的进程已经是进程组长,这个函数会返回一个错误。为了保证不会发生这种情况,在平时的练习中,先是调用fork,之后结束父进程,子进程继续运行。我们可以保证子进程不是进程组长,因为父进程的进程组ID被子进程继承,但是子进程的ID是新分配的。因此子进程的进程ID不可能等于它继承过来的进程组ID.
Single UNIX Specification只有“会话长”这个概念。这里没有类似进程组ID或进程ID一样的“会话ID”的概念。很明显,会话长是一个有唯一进程ID的单独进程,所以我们可以和这个会话长通讯。这种会话ID的概念是从SVR4引入的。历史上,基于BSD的系统不支持这种概念,但是也已经开始更新包含它。getsid函数返回一个进程的会话长的进程组ID。getsid函数已经做为XSI扩展被包含在Single UNIX Specification中。
会话ID和“会话长的进程组ID”相等,因为会话长一直是进程组长。
getsid函数返回进程会话长的进程组ID。
|
如果pid是0(零),getsid返回调用进程的会话长的进程组ID。出于安全原因,如果pid和调用进程不在同一会话的话,一些实现可以限制调用进程获得会话长的进程组ID。