探究终端会话与孤儿进程组的问题
作者:玩玩ftgcriug | 来源:互联网 | 2024-11-26 10:42
本文探讨了如何使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后,两个进程均会响应并输出相应的消息。
推荐阅读
本文详细介绍了 Dockerfile 的编写方法及其在网络配置中的应用,涵盖基础指令、镜像构建与发布流程,并深入探讨了 Docker 的默认网络、容器互联及自定义网络的实现。 ...
[详细]
蜡笔小新 2024-12-27 17:31:41
本文将介绍如何编写一些有趣的VBScript脚本,这些脚本可以在朋友之间进行无害的恶作剧。通过简单的代码示例,帮助您了解VBScript的基本语法和功能。 ...
[详细]
蜡笔小新 2024-12-28 09:46:23
本文介绍了一款用于自动化部署 Linux 服务的 Bash 脚本。该脚本不仅涵盖了基本的文件复制和目录创建,还处理了系统服务的配置和启动,确保在多种 Linux 发行版上都能顺利运行。 ...
[详细]
蜡笔小新 2024-12-27 16:33:32
本文详细解析了Python中的os和sys模块,介绍了它们的功能、常用方法及其在实际编程中的应用。 ...
[详细]
蜡笔小新 2024-12-26 22:04:19
本文详细介绍了如何在Linux系统上安装和配置Smokeping,以实现对网络链路质量的实时监控。通过详细的步骤和必要的依赖包安装,确保用户能够顺利完成部署并优化其网络性能监控。 ...
[详细]
蜡笔小新 2024-12-27 19:31:05
ImmutableX is set to spearhead the evolution of Web3 gaming, with its innovative technologies and strategic partnerships driving significant advancements in the industry. ...
[详细]
蜡笔小新 2024-12-27 08:55:17
学习链接:http:blog.csdn.netlwt36articledetails48908031学习扫描线主要学习的是一种扫描的思想,后期可以求解很 ...
[详细]
蜡笔小新 2024-12-26 20:04:36
SRIOV介绍、VF直通配置,以及包转发率性能测试小慢哥的原创文章,欢迎转载目录?1.SRIOV介绍?2.环境说明?3.开启SRIOV?4.生成VF?5.VF ...
[详细]
蜡笔小新 2024-12-25 19:26:39
本文探讨了在Java中实现系统托盘最小化的两种方法:使用SWT库和JDK6自带的功能。通过这两种方式,开发者可以创建跨平台的应用程序,使窗口能够最小化到系统托盘,并提供丰富的交互功能。 ...
[详细]
蜡笔小新 2024-12-25 15:03:50
本文详细介绍了Shell脚本编程的基础概念、语法结构及其在操作系统中的应用。通过具体的示例代码,帮助读者掌握如何编写和执行Shell脚本。 ...
[详细]
蜡笔小新 2024-12-25 06:58:01
本文介绍了如何使用 Spring Boot DevTools 实现应用程序在开发过程中自动重启。这一特性显著提高了开发效率,特别是在集成开发环境(IDE)中工作时,能够提供快速的反馈循环。默认情况下,DevTools 会监控类路径上的文件变化,并根据需要触发应用重启。 ...
[详细]
蜡笔小新 2024-12-28 04:42:15
Java 中的 BigDecimal pow()方法,示例 ...
[详细]
蜡笔小新 2024-12-27 20:54:03
本文探讨了Java中类成员的初始化顺序、静态引入、可变参数以及finalize方法的应用。通过具体的代码示例,详细解释了这些概念及其在实际编程中的使用。 ...
[详细]
蜡笔小新 2024-12-27 19:39:42
本文介绍了Java并发库中的阻塞队列(BlockingQueue)及其典型应用场景。通过具体实例,展示了如何利用LinkedBlockingQueue实现线程间高效、安全的数据传递,并结合线程池和原子类优化性能。 ...
[详细]
蜡笔小新 2024-12-27 18:51:49
本文由瀚高PG实验室撰写,详细介绍了如何在PostgreSQL中创建、管理和删除模式。文章涵盖了创建模式的基本命令、public模式的特性、权限设置以及通过角色对象简化操作的方法。 ...
[详细]
蜡笔小新 2024-12-26 11:37:26
玩玩ftgcriug
这个家伙很懒,什么也没留下!