《UNIX环境高级编程》笔记--进程组

每个进程都属于一个进程组。进程组通常是与同一个作业相关联的,可以接受来自同一个终端的各种信号。每个进程组都有

一个唯一的进程组ID。进程组ID类似于进程ID,可以存放在pid_t数据类型中。函数getpgrp返回调用进程的进程组ID。

#include <unistd.h>
pid_t getpgrp(void); //返回值:调用进程的进程组ID。
每个进程都可以有一个组长进程,组长进程的标识是:进程组ID等于其进程ID。

实践:

#include <stdio.h>
#include <unistd.h>

int main(){
        printf("pgrp=%d,pid=%d\n",getpgrp(),getpid());
        return 0;
}
运行结果:

pgrp=590,pid=590

可见该进程就是进程组长。


组长进程可以创建一个进程组,创建该组中的进程,然后终止,只要在某个进程中的有一个进程存在,则该进程组就存在,

这与其组长进程是否终止无关。进程组中的最后一个进程可以终止,或者转移到另一个进程组。

进程可以通过调用setpgid来加入一个现有的组或者创建一个新进程组。

#include <unistd.h>
int setpgid(pid_t pid, pid_t pgid);
//返回值:若成功则返回0,出错则返回-1.
setpgid函数将pid进程的进程组设置为pgid。如果这两个参数相等,则由pid指定的进程变成进程组组长。如果pid是0,则

使用调用者的进程ID。另外,如果pgid是0,则由pid指定的进程ID将用作进程组ID。

一个进程智能为它自己或者它的子in成设置进程组ID,在它的子进程调用了exec函数之一后,它就不能再改变该子进程的进程

组ID。

在大多数作业控制shell中,在fork之后调用此函数,使父进程设置其子进程的进程组ID,并且使子进程设置其自己的进程组ID,

这2个调用中有一个是冗余的,但是让父子进程组都这么做可以保证子进程成为新的进程组的组长。

实践:

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/wait.h>

int main(){
        pid_t pid;
        if((pid=fork())<0){
                perror("fork");
                return -1;
        }else if(pid == 0){
                setpgid(getpid(),getpid());
                printf("child pgrpid=%d,pid=%d\n",getpgrp(),getpid());
                exit(0);
        }
        setpgid(pid,pid);
        printf("parent pgrpid=%d,pid=%d\n",getpgrp(),getpid());
        waitpid(pid,NULL,0);
        return 0;
}

运行结果:

parent pgrpid=1996,pid=1996
child pgrpid=1997,pid=1997

你可能感兴趣的:(《UNIX环境高级编程》笔记--进程组)