1

我有一个关于 Linux 系统中信号的简单问题。据我了解,每个过程都有它的PIDPGID。当我创建一个进程时,它会变得独一无二PID,现在如果我要创建一个具有fork()功能的新进程,我会得到具有不同PID但相同的子进程PGID

现在,代码

#include<stdio.h>
#include<unistd.h>
int main()
{
  int i=3;
  int j;
  for(j=0;j<i;++j)
  {
      if (fork() == 0)
      {
          while(1)
          {

          }
      }
  }
  printf("created\n");
  while(1)
  {

  }
  return 0;
}

当我编译这个程序并使用命令运行它时

./foo

等一下,他创建了他的孩子,我做CTRL-C,然后ps aux我可以看到父母和孩子都走了,但如果我这样做

./foo

等待分叉完成并在其他终端执行

kill -INT <pid_of_foo>

ps aux我可以看到父母已经走了,但孩子们还活着,正在吃我的 CPU 。

我不确定,但似乎CTRL-C将信号发送到某个进程组中的每个进程,并且KILL -SIGNAL pid命令将信号发送到带有PID=pidnot的进程PGID=pid

我在正确的轨道上吗?如果是,为什么组合键会杀死进程PGID而不是PID

4

1 回答 1

2

信号传递、进程组和会话

是的,你在正确的轨道上。

自 BSD 发布以来的现代 Unix 变体实现了会话进程组

您可以将会话视为一组进程组。这个想法是,在 tty 或伪 tty 线上单次登录所产生的所有内容都是会话的一部分,与单个 shell 管道或其他逻辑进程分组相关的内容将被组织到单个进程组中。

这使得在前台和后台之间移动“工作”和传递信号更加方便。shell用户大多不需要担心单个进程,而是可以直观地控制-C一组相关命令。

键盘生成的信号在会话中被发送到前台进程组。您正在使用的 CLIkill命令将信号传递给各个进程。如果您想尝试复制 ^C 传递机制,您可以使用kill 0;这会将信号发送给同一进程组的每个成员,如果从脚本执行,它可能会执行您想要的操作。


注意:我编辑了您的问题以将 GPID 更改为 PGID。

于 2012-05-12T19:21:06.487 回答