二十八、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 }

 

posted @ 2018-06-11 21:49  游戏进行中  阅读(1053)  评论(0编辑  收藏  举报