热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

探究终端会话与孤儿进程组的问题

本文探讨了如何使Shell和程序同时响应Ctrl-C信号的方法,即通过将两者置于同一进程组并将其设为终端的前台进程组。
为了使Shell和某个程序能够同时接收到Ctrl-C信号,最有效的方式是将这两个进程设置在同一进程组,并且将此进程组设置为终端的前台进程组。例如,假设当前终端上的Bash进程PID为2774,可以通过以下C语言代码实现这一目标:

```c
#include
#include
#include

void handler(int n) {
printf("Caught SIGINT\n");
}

int main() {
setpgid(0, 2774); // 将test程序和bash设置为同一进程组
signal(SIGINT, handler);
while (1) {
sleep(1);
// kill(0, SIGINT); // 先注释掉
}
}
```

编译上述代码为`test`,并在运行前设置Bash的陷阱以捕获SIGINT信号:

```bash
trap 'echo Caught SIGINT' INT
```

理想情况下,运行`test`后按下Ctrl-C,屏幕上应显示“Caught SIGINT”和“Caught SIGINT”,但实际上没有任何输出。这涉及到控制终端、进程组等概念。具体来说,当Bash通过fork-exec启动`test`时,已调用`ioctl(fd, TIOCSPGRP, &子进程PID)`,这将子进程(即`test`)的PID设置为TTY的pgrp字段。通过`strace`命令或查看Bash和Linux内核源码可以验证这一点。当内核接收到Ctrl-C时,会将该信号作为普通字符放入终端接收缓冲区,随后调用终端行规程的`receive_buf`处理这些字符。一旦检测到Ctrl-C控制字符,会触发`isig`函数,进而调用`kill_pg(tty->pgrp, sig, 1)`向指定进程组发送信号。由于Bash已将TTY的pgrp更改为`test`的PID,而`test`在调用`setpgid`时从PGID表中脱离,导致没有进程接收到信号。

若取消对`kill`代码行的注释并重新编译运行,虽然`test`能正确显示“Caught SIGINT”,但Bash的相应消息未出现,原因是此时终端被`test`独占,尽管SIGINT已挂起于Bash。要解决这个问题,尝试恢复TTY的pgrp至Bash的PID,例如使用`tcsetpgrp(fd, 2774)`或`ioctl(fd, TIOCSPGRP, &id)`。然而,这些调用均失败,因为`test`无法更改TTY的pgrp。根据POSIX标准,不允许将孤儿进程组设置为TTY的前台进程组,孤儿进程组指组内所有成员要么与其父进程在同一组,要么分属不同会话,从而实现终端信号的隔离。在本例中,`test`设置后的进程组成为孤儿进程组,因此后续的`TIOCSPGRP`调用无效。

若需实现Ctrl-C同时影响两个进程,可在启动`test`时使用后台模式(`test &`),这样Bash不会调用`ioctl`让子进程独占终端,而是保持自身对终端的控制。这样一来,按下Ctrl-C后,两个进程均会响应并输出相应的消息。
推荐阅读
  • 本文分享了作者在使用LaTeX过程中的几点心得,涵盖了从文档编辑、代码高亮、图形绘制到3D模型展示等多个方面的内容。适合希望深入了解LaTeX高级功能的用户。 ... [详细]
  • GCC(GNU Compiler Collection)是GNU项目下的一款功能全面且高效的多平台编译工具,广泛应用于Linux操作系统中。本文将详细介绍GCC的特点及其基本使用方法。 ... [详细]
  • 本文详细介绍了如何在 EasyUI 框架中实现 DataGrid 组件的分页功能,包括配置方法和常见问题的解决方案。 ... [详细]
  • 本文探讨了Linux/Unix文件系统中两种主要的权限控制方式:传统的UGO(User/Group/Others)和更为精细的ACL(Access Control List)。ACL提供了一种更灵活的权限管理方法,适用于需要对文件系统进行细粒度控制的场景。 ... [详细]
  • C/C++ 应用程序的安装与卸载解决方案
    本文介绍了如何使用Inno Setup来创建C/C++应用程序的安装程序,包括自动检测并安装所需的运行库,确保应用能够顺利安装和卸载。 ... [详细]
  • HDU1085 捕获本·拉登!
    问题描述众所周知,本·拉登是一位臭名昭著的恐怖分子,他已失踪多年。但最近有报道称,他藏匿在中国杭州!虽然他躲在杭州的一个洞穴中不敢外出,但近年来他因无聊而沉迷于数学问题,并声称如果有人能解出他的题目,他就自首。 ... [详细]
  • ZOJ 2760 - 最大流问题
    题目链接:How Many Shortest Paths。题目描述:给定一个包含n个节点的有向图,通过一个n*n的矩阵来表示。矩阵中的a[i][j]值为-1表示从节点i到节点j无直接路径;否则,该值表示从i到j的路径长度。输入起点vs和终点vt,计算从vs到vt的所有不共享任何边的最短路径数量。如果起点和终点相同,则输出无穷大。 ... [详细]
  • 在Android应用开发中,当在MenuItem中通过app:actionLayout属性使用Switch控件时,可能会遇到空指针异常的问题。本文将探讨该问题的原因及解决方案。 ... [详细]
  • A1166 峰会区域安排问题(25分)PAT甲级 C++满分解析【图论】
    峰会是指国家元首或政府首脑之间的会议。合理安排峰会的休息区是一项复杂的工作,理想的情况是邀请的每位领导人都是彼此的直接朋友。 ... [详细]
  • 2022年4月15日的算法练习题,包括最长公共子序列和线段树的应用。 ... [详细]
  • 本题要求计算从起点到终点所有最短路径的总权重,使用SPFA算法进行求解。 ... [详细]
  • 本文介绍了进程的基本概念及其在操作系统中的重要性,探讨了进程与程序的区别,以及如何通过多进程实现并发和并行。文章还详细讲解了Python中的multiprocessing模块,包括Process类的使用方法、进程间的同步与异步调用、阻塞与非阻塞操作,并通过实例演示了进程池的应用。 ... [详细]
  • 在尝试使用Ubuntu 10.04进行Android开发时,遇到了系统无法识别HTC G1设备的情况。本文将详细介绍如何通过配置系统和安装必要的驱动来解决这一问题。 ... [详细]
  • 本文详细介绍了如何使用 Python 编程语言中的 Scapy 库执行 DNS 欺骗攻击,包括必要的软件安装、攻击流程及代码示例。 ... [详细]
  • 本文详细介绍了Golang中string类型的内部结构及其特性,包括字符串的定义、表示方式、数据结构以及相关的操作方法,如字符串拼接和类型转换等。 ... [详细]
author-avatar
玩玩ftgcriug
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有