3

为什么组长无法创建会话。但是,除了组长之外能够创建会话吗?

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>

main() {

    int pid;
    int ppid=getppid();

    if ( setsid() < 0)
         perror("ERROR");

    if((pid=fork()) == 0)
    {
        printf("proces1=%d %d\n",getpid(),getpgrp());
        int s=getpgrp();

        //setpgid(pid,pid);
        if (setpgid(pid,0) < 0)
            perror("ERROR");

        printf("group after proces=%d %d\n",getpid(),getpgrp());
        exit(0);
    }

    wait(0);
    printf("group after proces=%d %d\n",getpid(),getpgrp());       
}                   

请解释。

4

1 回答 1

6

简短的回答

POSIX要求setsid()在进程组领导中禁止:

setsid()如果调用进程不是进程组负责人,该函数将创建一个新会话。

需要确保进程组的所有成员都是同一会话的成员。

长答案

进程组 ID 是进程组组长的 PID。会话 ID 是会话领导者的 PID。调用成功后setsid(),进程组ID、会话ID和PID应该相同。

但是,对于进程组组长,进程组 ID 已经等于 PID。如果它能够调用setsid(),它的进程组 ID 保持不变,因此:

  • 进程组长属于新会话;
  • 其他进程组成员属于旧会话。

因此,在这种情况下,我们有一个进程组,其成员属于不同的会话。POSIX 想要禁止这种情况。

为什么?

流程组和会话是为作业控制而发明的。进程组用于确定前台和后台组,以便前台组接收来自终端的信号。

为了实现这一点,终端跟踪其当前的前台进程组,并在某些事件发生时向该组发送信号。

但这假设来自任何给定进程组的所有进程共享相同的控制终端,因此终端发送的信号对它们有意义。

控制终端由以下规则共享:

  • 来自同一会话的所有进程共享同一控制终端;
  • 来自不同会话的进程不能共享同一个控制终端。

因此,如果我们要求一个进程组的所有成员共享同一个控制终端,我们也应该要求他们是同一个会话的成员

参考

请参阅“Linux 编程接口”,第 34 章(进程组、会话和作业控制)。

于 2015-01-15T11:02:29.163 回答