二十八、Linux 进程与信号---前台进程组
28.1 介绍
28.1.1 概念
- 自动接受终端信号的组称为前台进程组
- 在终端通过 ctrl + c 等动作产生的信号首先被前台进程组接受
- 在 shell 启动的若干个进程组默认是父进程所在的组为前台进程组
- 除非是默认,否则都要通过调度才能成为前台进程组
28.1.1 函数 tcgetpgrp 和 tcsetpgrp
(1)tcgetpgrp 函数---获得前台进程组ID
#include <unistd.h> int tcgetpgrp(int fd);
- 函数功能:获得前台进程组 ID
- 返回值:若成功返回前台进程组ID,出错返回 -1
(2)tcsetpgrp 函数---设置前台进程组ID
1 #include <unistd.h> 2 int tcsetpgrp(int fd, pid_t pgrpid);
- 函数功能:使用 pgrpid 设置前台进程组ID,fd 必须引用该会话的控制终端,0 代表当前正在使用的终端
- 返回值:成功返回 0,出错返回 -1
28.2 例子
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <unistd.h> 4 #include <sys/wait.h> 5 6 int main(void) 7 { 8 pid_t group1,group2; 9 10 //创建进程组1,父进程作为组长进程 11 setpgid(getpid(), getpid()); 12 group1 = getpgid(getpid()); 13 14 pid_t pid; 15 int i = 0; 16 for(; i < 3; i++) { 17 pid = fork(); 18 if(pid < 0) { 19 perror("fork error"); 20 exit(1); 21 } else if(pid > 0) { 22 if(i == 0) { 23 setpgid(pid, pid); 24 group2 = getpgid(pid); 25 } 26 27 if(i == 1) { 28 setpgid(pid, group2); 29 } 30 31 if(i == 2) { 32 setpgid(pid, group1); 33 } 34 } else { 35 36 if(i == 0) { 37 setpgid(getpid(), getpid()); 38 group2 = getpgid(getpid()); 39 } 40 41 if(i == 1) { 42 setpgid(getpid(), group2); 43 } 44 45 if(i == 2) { 46 setpgid(getpid(), group1); 47 } 48 49 break; 50 } 51 } 52 53 printf("pid: %d, ppid: %d, pgid: %d\n", getpid(), getppid(), getpgid(0)); 54 pause(); 55 56 exit(0); 57 }
编译执行
查询下进程:
按下 ctrl-c 停止运行的进程
然后再查看进程:
8956 和 8959 为默认进程组 group1,执行完 ctrl +c 后关闭,但是 group2 没有关闭,可以发现进程组默认是父进程那一组
进行设置 group2 为前台进程组
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <unistd.h> 4 #include <sys/wait.h> 5 6 int main(void) 7 { 8 pid_t group1,group2; 9 10 //创建进程组1,父进程作为组长进程 11 setpgid(getpid(), getpid()); 12 group1 = getpgid(getpid()); 13 14 pid_t pid; 15 int i = 0; 16 for(; i < 3; i++) { 17 pid = fork(); 18 if(pid < 0) { 19 perror("fork error"); 20 exit(1); 21 } else if(pid > 0) { 22 if(i == 0) { 23 setpgid(pid, pid); 24 group2 = getpgid(pid); 25 } 26 27 if(i == 1) { 28 setpgid(pid, group2); 29 30 //将 group2 设置为前台进程组 31 tcsetpgrp(0, group2); 32 } 33 34 if(i == 2) { 35 setpgid(pid, group1); 36 } 37 } else { 38 39 if(i == 0) { 40 setpgid(getpid(), getpid()); 41 group2 = getpgid(getpid()); 42 } 43 44 if(i == 1) { 45 setpgid(getpid(), group2); 46 47 tcsetpgrp(0, group2); 48 } 49 50 if(i == 2) { 51 setpgid(getpid(), group1); 52 } 53 54 break; 55 } 56 } 57 58 printf("pid: %d, ppid: %d, pgid: %d\n", getpid(), getppid(), getpgid(0)); 59 pause(); 60 61 exit(0); 62 }