4. 前台进程组
(1)前台进程组
①自动接受终端信号的组称为前台进程组
②在终端通过ctrl+c等动作产生的信号首先被前台进程组接受。
③在shell启动的若干个进程组默认是父进程所在的组为前台进程组,其他进程组则为后台进程组
④除非是默认,否则都要通过调度才能成为前台进程组
(2)获取/设置前台进程组ID
头文件 |
#include <unistd.h> |
函数 |
pid_t tcgetpgrp(int fd); //获取前台进程组ID,出错返回-1 int tcsetpgrp(int fd, pid_t pgrpid); //设置前台进程组ID,成功返回0,出错返回-1 |
功能 |
获取或设置前台进程组ID |
参数 |
fd:必须引用该会话的控制终端,0代表当前正在使用的终端 |
【编程实验】设置前台进程组
//process_foregroup.c
#include <unistd.h> #include <stdio.h> #include <stdlib.h> //测试前台进程组 //分为前台进程组和后台进程组,按ctrl+c时前台进程组将被kill。 int main(void) { pid_t group1, group2; //创建进程组1,父进程作为组长进程 setpgid(getpid(), getpid()); group1 = getpgid(getpid()); pid_t pid; int i = 0; for(; i< 3; i++){ pid = fork(); if(pid < 0){ perror("fork error"); exit(1); }else if(pid > 0){ //parent process if(i == 0 ){ //创建进程组2 setpgid(pid, pid); group2 = getpgid(pid); //将group2设置为前台进程组 tcsetpgrp(0, group2); } if(i == 1){ //将第2个子进程加入到group2 setpgid(pid, group2); } if(i == 2){ //第3个子进程加入group1 setpgid(pid, group1); } }else{ //child process if(i == 0){ //创建进程组2 setpgid(getpid(), getpid()); group2 = getpgid(getpid()); //将group2设置为前台进程组 tcsetpgrp(0, group2); } if(i == 1){ //将第2个子进程加入到group2 setpgid(getpid(), group2); } if(i == 2){ //第3个子进程加入group1 setpgid(getpid(), group1); } break; //进程扇,子进程须退出 } } printf("pid: %d, ppid: %d, pgid: %d\n", getpid(), getppid(), getpgid(0)); pause(); return 0; }