二十八、Linux 进程与信号---前台进程组

时间:2022-06-02 08:11:22

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

 #include <unistd.h>
int tcsetpgrp(int fd, pid_t pgrpid);
  • 函数功能:使用 pgrpid 设置前台进程组ID,fd 必须引用该会话的控制终端,0 代表当前正在使用的终端
  • 返回值:成功返回 0,出错返回 -1

28.2 例子

  二十八、Linux 进程与信号---前台进程组

 #include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h> int main(void)
{
pid_t group1,group2; //创建进程组1,父进程作为组长进程
setpgid(getpid(), getpid());
group1 = getpgid(getpid()); pid_t pid;
int i = ;
for(; i < ; i++) {
pid = fork();
if(pid < ) {
perror("fork error");
exit();
} else if(pid > ) {
if(i == ) {
setpgid(pid, pid);
group2 = getpgid(pid);
} if(i == ) {
setpgid(pid, group2);
} if(i == ) {
setpgid(pid, group1);
}
} else { if(i == ) {
setpgid(getpid(), getpid());
group2 = getpgid(getpid());
} if(i == ) {
setpgid(getpid(), group2);
} if(i == ) {
setpgid(getpid(), group1);
} break;
}
} printf("pid: %d, ppid: %d, pgid: %d\n", getpid(), getppid(), getpgid());
pause(); exit();
}

  编译执行

  二十八、Linux 进程与信号---前台进程组

  查询下进程:

  二十八、Linux 进程与信号---前台进程组

  按下 ctrl-c 停止运行的进程

  然后再查看进程:

  二十八、Linux 进程与信号---前台进程组

  8956 和 8959 为默认进程组 group1,执行完 ctrl +c 后关闭,但是 group2 没有关闭,可以发现进程组默认是父进程那一组

  进行设置 group2 为前台进程组

 #include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h> int main(void)
{
pid_t group1,group2; //创建进程组1,父进程作为组长进程
setpgid(getpid(), getpid());
group1 = getpgid(getpid()); pid_t pid;
int i = ;
for(; i < ; i++) {
pid = fork();
if(pid < ) {
perror("fork error");
exit();
} else if(pid > ) {
if(i == ) {
setpgid(pid, pid);
group2 = getpgid(pid);
} if(i == ) {
setpgid(pid, group2); //将 group2 设置为前台进程组
tcsetpgrp(, group2);
} if(i == ) {
setpgid(pid, group1);
}
} else { if(i == ) {
setpgid(getpid(), getpid());
group2 = getpgid(getpid());
} if(i == ) {
setpgid(getpid(), group2); tcsetpgrp(, group2);
} if(i == ) {
setpgid(getpid(), group1);
} break;
}
} printf("pid: %d, ppid: %d, pgid: %d\n", getpid(), getppid(), getpgid());
pause(); exit();
}