70-设置前台进程组

如果一个会话有控制终端,那么该会话就有一个前台进程组。此时在终端中的输入以及终端产生的信号默认都发送给前台进程组中的所有进程。

前台进程组是可以通过程序进行设置的。在同一个会话中,调用 tcsetpgrp 函数可以设置某个进程组为前台进程组。

1. 目标

任务1: 在 bash 中启动你的进程,然后将前台进程组设置为 bash 所在的进程组。
任务2:关闭启动你进程的终端,查看你的进程能收到什么信号。

2. 思路

在任务 1 中,首先获取 bash 进程的进程组 id,而 bash 进程又是进程组组长,所以它的进程组 id 就相当于 bash 进程 id.

任务 2 中,你的进程可以收到 SIGHUP 信号,所以捕获些信号即可(有关信号的知识请参考专题五)。

3. 程序清单

  • 代码
// ct.c
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>

void handler(int sig) {
  if (sig == SIGHUP) {
    int fd = open("tmp", O_WRONLY | O_CREAT, 0664);
    write(fd, "hello SIGHUP\n", 32);
    exit(0);
  }
}

void print() {
  pid_t pid, sid, pgid, tpgid;

  pid = getpid();
  sid = getsid(pid);
  pgid = getpgid(pid);
  tpgid = tcgetpgrp(0);
  if (tpgid < 0) {
    perror("tcgetpgrp");
  }

  printf("pid = %d, pgid = %d, sid = %d, tpgid = %d\n", pid, pgid, sid, tpgid);
}
int main(int argc, char* argv[]) {
  signal(SIGHUP, handler);

  // 打印当前进程 id,组 id,会话 id,当前会话中的前台进程组 id.
  print();

  // 将前台进程组设置为 bash 进程组的 id.
  tcsetpgrp(0, getppid());

  print();

  while(1) sleep(1);
  return 0;
}
  • 编译和运行
$ gcc ct.c -o ct
$ ./ct
  • 运行结果


这里写图片描述
图1 运行结果

启动你的程序后,无论键入 CTRL C、CTRL \ 还是 CTRL Z 都没反应了。程序第一行打印的是未设置前台进程组前的结果,第二行打印是设置后的结果。可以看到设置后的前台进程组 id = 2816.

直接关闭终端,当前文件夹下会生成 tmp 文件,内容就是在信号处理函数里定稿的数据,如图2。


这里写图片描述
图2 关闭终端,进程收到 SIGHUP 信号

4. 总结

  • 掌握如何设置前台进程组
  • 当直接关闭控制终端后,进程会收到 SIGHUP 信号

练习:使用 kill 将启动 ct 程序的 bash 进程杀死,看看有什么效果。(提示:ct 进程并没有结束,因为没有收到 SIGHUP 信号)

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值