Answers:
在Linux中,每个进程都有几个与之关联的ID,包括:
进程ID(PID)
这是标识进程的任意数字。每个进程都有一个唯一的ID,但是在进程退出并且父进程检索到退出状态后,该进程ID将被释放以供新进程重用。
父进程ID(PPID)
这只是启动有问题的进程的进程的PID。
流程组ID(PGID)
这只是流程组负责人的PID。如果PID == PGID,则此流程为流程组负责人。
会话ID(SID)
这只是会话领导者的PID。如果PID == SID,则此过程为会话负责人。
会话和流程组只是将多个相关流程视为一个单元的方式。进程组的所有成员始终属于同一会话,但是一个会话可能具有多个进程组。
通常,外壳将是会话领导者,并且该外壳执行的每个管道都将是一个进程组。这使退出外壳时杀死外壳的子级变得容易。(有关gory的详细信息,请参阅exit(3)。)
我认为不是领导者的会话或流程组成员没有特殊的用语。
会话负责人是一个进程,其中会话ID ==进程ID。这听起来是人为的,但是会话ID是由子进程继承的。UNIX / Linux中的某些操作在进程会话上进行,例如,在发送给kill系统调用或命令时取消进程ID。最常见的用法是注销shell时。操作系统将发送kill -HUP -$$
,这将向与会话具有相同会话ID的所有进程发送SIGHUP(挂断)信号。当您放弃一个进程时,该进程的会话ID会从Shell中更改,因此它不会响应挂断信号。这是成为守护进程的过程的一部分。
从窗口管理器/图形环境调用的大多数进程都具有与启动程序之一相同的会话ID。这使操作系统可以kill -HUP -$$
在所有程序上执行相同的操作:例如您的浏览器,音乐播放器,libreoffice,IM客户端等。这些进程不是会话引导程序。
我以为我知道答案,但是我写了一个C程序来解决这个问题。
#include <stdio.h>
#include <unistd.h>
int
main(int ac, char **av)
{
pid_t sid, mypid, pgid, gid;
mypid = getpid();
sid = getsid(0);
pgid = getpgid(0);
gid = getpgrp();
printf("PID %d\n", mypid);
printf("process group ID of session leader: %d\n", sid);
printf("process group ID: %d\n", pgid);
printf("process group ID: %d\n", gid);
if (!fork())
{
mypid = getpid();
sid = getsid(0);
pgid = getpgid(0);
gid = getpgrp();
printf("child PID %d\n", mypid);
printf("process group ID of session leader: %d\n", sid);
printf("process group ID: %d\n", pgid);
printf("process group ID: %d\n", gid);
_exit(0);
}
return 0;
}
我用cc -g -o sid sid.c
几种不同的方式来运行它,以查看发生了什么:
./sid
nohup ./sid > sid.out
setsid ./sid
我对Linux(2.6.39)的回报感到惊讶。我还找到了第7节手册页“凭据”。
我的建议是这样做man 7 credentials
(如果不在Linux上,则建议这样做),并阅读有关进程组和会话的部分,以查看是否可以解决这个问题。
./sid
和nohup ./sid
,并且在运行setsid ./sid
时,会话ID(SID)是全新的,是一样的过程PID ...我我不确定为什么nohup阻止了叉子(或似乎阻止了叉子),但我想我已经有了大致的想法...
ps xao pid,ppid,pgid,sid,comm
用于查看这些ID。