《UNIX环境高级编程》笔记--会话

来源:互联网 发布:linux终端退出服务器 编辑:程序博客网 时间:2024/05/18 01:58

会话(session)是一个或者多个进程组的集合。可以具有下图所有的安排,其中,一个会话中有3个进程组。


上图的安排可能由以下形式的shell命令形成的:

proc1 | proc2 &

proc3 | proc4 | proc5

进程调用setsid函数建立一个新会话。

#include <unistd.h>pid_t setsid(void); //若成功则返回进程组ID,出错则返回-1.

1.如果调用此函数的进程不是一个进程组组长,则此函数就会创建一个新会话,结果将发生下面三件事:

a.该进程变成新会话首进程(session leader)。(会话首进程是创建该会话的进程)此时,该进程是新会话中的唯一进程。

b.该进程称为一个新进程组的组长进程,新进程组ID是该调用进程的进程ID。

c.该进程没有控制终端,如果在调用setsid之前该进程有一个控制终端,那么这种联系也会被中断。

2.如果该调用进程已经是一个进程组的组长,则此函数返回出错。为了保证不会发生这种情况,通常先调用fork,然后使其父进程

终止,则子进程则继续。因为子进程继承了父进程的进程组ID,而其进程ID是新分配的,保证了子进程不会是一个进程组的组长。


getsid函数返回会话首进程的进程组ID。

#include <unistd.h>pid_t getsid(pid_t pid); //若成功则返回会话首进程ID,出错则返回-1.
若pid是0,则返回调用进程的会话首进程的进程组ID。


实践:

#include <stdio.h>#include <unistd.h>#include <stdlib.h>#include <sys/wait.h>int main(){        pid_t pid;        if((pid=fork())<0){                perror("fork");                return -1;        }else if(pid == 0){                pid_t sid;                sid = getsid(0);                printf("in child(before setsid) sid=%d\n",sid);                sid = setsid();                printf("in child(after setsid) sid=%d\n",sid);                printf("in child sid=%d,pgrpid=%d,pid=%d\n",sid, getpgrp(),getpid());                exit(0);        }        pid_t sid;        sid = setsid();        printf("in parent sid=%d,pgrpid=%d,pid=%d\n",sid,getpgrp(),getpid());        sid = getsid(0);        printf("in parent sid=%d\n",sid);        sid = getsid(pid);        printf("in parent get child sid=%d\n",sid);        sid = getsid(1);        printf("in parent get init sid=%d\n",sid);        waitpid(pid,NULL,0);        return 0;}
运行结果:
in parent sid=-1,pgrpid=7084,pid=7084
in parent sid=6851
in parent get child sid=6851
in parent get init sid=1
in child(before setsid) sid=6851
in child(after setsid) sid=7085
in child sid=7085,pgrpid=7085,pid=7085

在父进程中,调用setsid,因为该进程是进程组组长(pid和pgrpid都是7084),所以返回-1。

获取父进程sid是6851。

在父进程中获取子进程sid也是6851。

在父进程中获取init的sid是1。(好像能获取任何进程的sid)

在子进程中获取sid是6851(此时和父进程子在同一个会话中)

在子进程中setsid后,子进程处在新的会话中,新会话的ID是7085,

在子进程中获取sid是7085,进程组ID和进程ID都是7085,说明该子进程是会话中的第一个进程,而且是进程组的组长。