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

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

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

proc1 | proc2 &

proc3 | proc4 | proc5

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

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

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

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

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

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

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

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


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

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


实践:

[cpp] view plain copy
  1. #include <stdio.h>  
  2. #include <unistd.h>  
  3. #include <stdlib.h>  
  4. #include <sys/wait.h>  
  5.   
  6.   
  7. int main(){  
  8.         pid_t pid;  
  9.         if((pid=fork())<0){  
  10.                 perror("fork");  
  11.                 return -1;  
  12.         }else if(pid == 0){  
  13.                 pid_t sid;  
  14.                 sid = getsid(0);  
  15.                 printf("in child(before setsid) sid=%d\n",sid);  
  16.                 sid = setsid();  
  17.                 printf("in child(after setsid) sid=%d\n",sid);  
  18.                 printf("in child sid=%d,pgrpid=%d,pid=%d\n",sid, getpgrp(),getpid());  
  19.                 exit(0);  
  20.         }  
  21.         pid_t sid;  
  22.         sid = setsid();  
  23.         printf("in parent sid=%d,pgrpid=%d,pid=%d\n",sid,getpgrp(),getpid());  
  24.         sid = getsid(0);  
  25.         printf("in parent sid=%d\n",sid);  
  26.         sid = getsid(pid);  
  27.         printf("in parent get child sid=%d\n",sid);  
  28.         sid = getsid(1);  
  29.         printf("in parent get init sid=%d\n",sid);  
  30.         waitpid(pid,NULL,0);  
  31.         return 0;  
  32. }  
运行结果:
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,说明该子进程是会话中的第一个进程,而且是进程组的组长。

相关文章:

  • 2022-12-23
  • 2021-11-18
  • 2021-10-21
  • 2021-08-17
  • 2021-04-23
猜你喜欢
  • 2021-04-18
  • 2022-01-15
  • 2021-09-11
  • 2021-07-14
  • 2021-11-26
  • 2021-07-04
  • 2021-12-12
相关资源
相似解决方案