http://www.zyfforlinux.cc/2014/11/20/%E8%BF%9B%E7%A8%8B%E9%97%B4%E5%85%B3%E7%B3%BB/
进程组的概念
每一个进程除了有一个进程ID之外,还属于一个进程组,进程组通常是一个或多个进程的集合。这些进程通常是与一个作业相关的。
例如:
ps axu|grep bash|wc -l 这是三个进程,他们直接通过管道传递数据,为了是完成一个作业,对于这个整体来说是一个进程组,
其中ps进程是进程组的组长进程。进程组也是由一个PID来标识进程组的,通过使用PGID来标识,然后这个PGID==进程组组长进程的PID的
使用下面的这个命令来验证这一事实:
1 2 3 4 5 6
|
[root@localhost common]
|
1 2 3 4 5 6 7 8 9
|
下面这两个方法是用来设置和获取进程组的方法 #include <unistd.h>
int setpgid(pid_t pid, pid_t pgid); 如果pid等于pgid,那么pid就成为了其所属的进程组的组长进程, 如果pid等于0,则标识把当前进程设置为pgid的组长进程 如果pgid等于0,则使用pid作为目标pgid
pid_t getpgid(pid_t pid);
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
|
#include <unistd.h> #include <stdio.h>
int main() { printf("%d\n",getpgid(getpid())); while(1); } 测试结果如下: a.out属于4082这个进程组的,并且是组长进程 [root@localhost ~]# ps -o pid,ppid,pgid,sid,comm a PID PPID PGID SID COMMAND 1698 815 1698 1698 bash 2445 2441 2445 2445 bash 4082 2445 4082 2445 a.out 4087 4083 4087 4087 bash 4206 4087 4206 4087 ps
|
会话的概念
会话就是一些有关联的进程组的集合,
1 2 3 4 5 6 7
|
[root@localhost ~]
|
1 2 3 4 5 6 7 8
|
#include <unistd.h> pid_t getsid(pid_t pid);
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
|
#include <unistd.h> #include <stdio.h>
int main() { setsid(); perror("setsid error"); while(1); } setsid error: Operation not permitted [root@localhost ~]# ps -o pid,ppid,pgid,sid,comm a PID PPID PGID SID COMMAND 1698 815 1698 1698 bash 2445 2441 2445 2445 bash 4087 4083 4087 4087 bash 4960 2445 4960 2445 a.out 4961 4087 4961 4087 ps
执行上面程序会出错,因为执行这个程序后,这个程序是一个进程组的组长进程,组长进程是无法调用setsid的,并且从上文我们知道这个程序和bash是属于一个会话的, 那么下面这个例子演示了通过子进程(子进程和父进程是属于同一个进程组,但是子进程不是组长进程)
#include <unistd.h> #include <stdio.h>
int main() { if(fork > 0)
|
进程之间的关系
下面是bash进程fork出ps 和more进程执行,之间的进程间关系。
