进程组

进程组就是一个或多个进程的集合,每个进程组都有唯一的进程组ID(整数,也可以存放在pid_t类型中),进程组由进程组ID来唯一标识,进程组ID是一个正整数,用来获得当前进程进程组ID的命令:

$ ps -ajx


显示如下:(PGID列即为进程组列)
 PPID   PID  PGID   SID TTY      TPGID STAT   UID   TIME COMMAND
    0     1     1     1 ?           -1 Ss       0   0:01 /sbin/init
    0     2     0     0 ?           -1 S        0   0:00 [kthreadd]
    2     3     0     0 ?           -1 S        0   0:00 [ksoftirqd/0]
    2     4     0     0 ?           -1 S        0   0:00 [kworker/0:0]
    2     5     0     0 ?           -1 S<       0   0:00 [kworker/0:0H]
    2     7     0     0 ?           -1 S        0   0:01 [rcu_sched]
    2     8     0     0 ?           -1 S        0   0:00 [rcu_bh]
    2     9     0     0 ?           -1 S        0   0:00 [migration/0]
    2    10     0     0 ?           -1 S        0   0:00 [watchdog/0]
    2    11     0     0 ?           -1 S<       0   0:00 [khelper]
    2    12     0     0 ?           -1 S        0   0:00 [kdevtmpfs]
    2    13     0     0 ?           -1 S<       0   0:00 [netns]
    2    14     0     0 ?           -1 S<       0   0:00 [writeback]
    2    15     0     0 ?           -1 S<       0   0:00 [kintegrityd]
    2    16     0     0 ?           -1 S<       0   0:00 [bioset]
    2    17     0     0 ?           -1 S<       0   0:00 [kworker/u17:0]
    2    18     0     0 ?           -1 S<       0   0:00 [kblockd]
    2    19     0     0 ?           -1 S<       0   0:00 [ata_sff]
    2    20     0     0 ?           -1 S        0   0:00 [khubd]
    2    21     0     0 ?           -1 S<       0   0:00 [md]
    2    22     0     0 ?           -1 S<       0   0:00 [devfreq_wq]
    2    25     0     0 ?           -1 S        0   0:00 [khungtaskd]

用来获得当前进程进程组ID的函数:

pid_t getpgid(pid_t pid)

pid_t getpgrp(void)

获得父子进程进程组 例子:

 1 #include <stdio.h>
 2 #include <stdlib.h>
 3 #include <unistd.h>
 4 int main(void)
 5 {
 6     pid_t pid;
 7     if ((pid = fork()) < 0) {
 8         perror("fork");
 9         exit(1);
10     }else if (pid == 0) {
11         printf("child process PID is %d
",getpid());
12         printf("Group ID is %d
",getpgrp());
13         printf("Group ID is %d
",getpgid(0));
14         printf("Group ID is %d
",getpgid(getpid()));
15         exit(0);
16     }
17     sleep(3);
18     printf("parent process PID is %d
",getpid());
19     printf("Group ID is %d
",getpgrp());
20     return 0;
21 }
22 
23 
24 输出结果:
25 child process PID is 3691
26 Group ID is 3690
27 Group ID is 3690
28 Group ID is 3690
29 parent process PID is 3690
30 Group ID is 3690

注: 
1)组长进程标识:其进程组ID==其进程ID 
2)组长进程可以创建一个进程组,创建该进程组中的进程,然后终止,只要进程组中有一个进程存在,进程组就存在,与组长进程是否终止无关 
3)进程组生存期:进程组创建到最后一个进程离开(终止或转移到另一个进程组) 
4)一个进程可以为自己或子进程设置进程组ID 

以下函数可以加入一个现有的进程组或创建一个新进程组

int setpgid(pid_t pid, pid_t pgid)

注: 
1)如要改变子进程为新的组,应在fork后,exec前使用 
2)非root进程只能改变自己创建的子进程,或有权限操作的进程

例子:(改变父子进程为新的组)

 1 #include <stdio.h>
 2 #include <stdlib.h>
 3 #include <unistd.h>
 4 int main(void)
 5 {
 6     pid_t pid;
 7     if ((pid = fork()) < 0) {
 8         perror("fork");
 9         exit(1);
10     } else if (pid == 0) {
11         printf("child process PID is %d
",getpid());
12         printf("Group ID of child is %d
",getpgid(0)); // 返回组id
13         sleep(5);
14         printf("Group ID of child is changed to %d
",getpgid(0));
15         exit(0);
16     }
17     sleep(1);
18     setpgid(pid,pid); // 父进程改变子进程的组id为子进程本身
19     sleep(5);
20     printf("parent process PID is %d
",getpid());
21     printf("parent of parent process PID is %d
",getppid());
22     printf("Group ID of parent is %d
",getpgid(0));
23     setpgid(getpid(),getppid()); // 改变父进程的组id为父进程的父进程
24     printf("Group ID of parent is changed to %d
",getpgid(0));
25     return 0;
26 }
27 
28 
29 
30 输出:
31 child process PID is 3714
32 Group ID of child is 3713
33 Group ID of child is changed to 3714
34 parent process PID is 3713
35 parent of parent process PID is 3305
36 Group ID of parent is 3713
37 Group ID of parent is changed to 3305
原文地址:https://www.cnblogs.com/13224ACMer/p/6413830.html