进程组就是一个或多个进程的集合,每个进程组都有唯一的进程组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)
获得父子进程进程组 例子:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(void)
{
pid_t pid;
if ((pid = fork()) < 0) {
perror("fork");
exit(1);
}else if (pid == 0) {
printf("child process PID is %d\n",getpid());
printf("Group ID is %d\n",getpgrp());
printf("Group ID is %d\n",getpgid(0));
printf("Group ID is %d\n",getpgid(getpid()));
exit(0);
}
sleep(3);
printf("parent process PID is %d\n",getpid());
printf("Group ID is %d\n",getpgrp());
return 0;
}
输出结果:
child process PID is 3691
Group ID is 3690
Group ID is 3690
Group ID is 3690
parent process PID is 3690
Group ID is 3690
注:
1)组长进程标识:其进程组ID==其进程ID
2)组长进程可以创建一个进程组,创建该进程组中的进程,然后终止,只要进程组中有一个进程存在,进程组就存在,与组长进程是否终止无关
3)进程组生存期:进程组创建到最后一个进程离开(终止或转移到另一个进程组)
4)一个进程可以为自己或子进程设置进程组ID
以下函数可以加入一个现有的进程组或创建一个新进程组:
int setpgid(pid_t pid, pid_t pgid)
注:
1)如要改变子进程为新的组,应在fork后,exec前使用
2)非root进程只能改变自己创建的子进程,或有权限操作的进程
例子:(改变父子进程为新的组)
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(void)
{
pid_t pid;
if ((pid = fork()) < 0) {
perror("fork");
exit(1);
} else if (pid == 0) {
printf("child process PID is %d\n",getpid());
printf("Group ID of child is %d\n",getpgid(0)); // 返回组id
sleep(5);
printf("Group ID of child is changed to %d\n",getpgid(0));
exit(0);
}
sleep(1);
setpgid(pid,pid); // 父进程改变子进程的组id为子进程本身
sleep(5);
printf("parent process PID is %d\n",getpid());
printf("parent of parent process PID is %d\n",getppid());
printf("Group ID of parent is %d\n",getpgid(0));
setpgid(getpid(),getppid()); // 改变父进程的组id为父进程的父进程
printf("Group ID of parent is changed to %d\n",getpgid(0));
return 0;
}
输出:
child process PID is 3714
Group ID of child is 3713
Group ID of child is changed to 3714
parent process PID is 3713
parent of parent process PID is 3305
Group ID of parent is 3713
Group ID of parent is changed to 3305