热门标签 | 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后,两个进程均会响应并输出相应的消息。
推荐阅读
  • 本文详细介绍了如何在Linux系统上安装和配置Smokeping,以实现对网络链路质量的实时监控。通过详细的步骤和必要的依赖包安装,确保用户能够顺利完成部署并优化其网络性能监控。 ... [详细]
  • 本文详细介绍了 Dockerfile 的编写方法及其在网络配置中的应用,涵盖基础指令、镜像构建与发布流程,并深入探讨了 Docker 的默认网络、容器互联及自定义网络的实现。 ... [详细]
  • 本文介绍了一款用于自动化部署 Linux 服务的 Bash 脚本。该脚本不仅涵盖了基本的文件复制和目录创建,还处理了系统服务的配置和启动,确保在多种 Linux 发行版上都能顺利运行。 ... [详细]
  • 本文将介绍如何编写一些有趣的VBScript脚本,这些脚本可以在朋友之间进行无害的恶作剧。通过简单的代码示例,帮助您了解VBScript的基本语法和功能。 ... [详细]
  • 本文由瀚高PG实验室撰写,详细介绍了如何在PostgreSQL中创建、管理和删除模式。文章涵盖了创建模式的基本命令、public模式的特性、权限设置以及通过角色对象简化操作的方法。 ... [详细]
  • 本文详细记录了在银河麒麟操作系统和龙芯架构上使用 Qt 5.15.2 进行项目打包时遇到的问题及解决方案,特别关注于 linuxdeployqt 工具的应用。 ... [详细]
  • golang常用库:配置文件解析库/管理工具viper使用
    golang常用库:配置文件解析库管理工具-viper使用-一、viper简介viper配置管理解析库,是由大神SteveFrancia开发,他在google领导着golang的 ... [详细]
  • Docker的安全基准
    nsitionalENhttp:www.w3.orgTRxhtml1DTDxhtml1-transitional.dtd ... [详细]
  • 本文将介绍如何使用 Go 语言编写和运行一个简单的“Hello, World!”程序。内容涵盖开发环境配置、代码结构解析及执行步骤。 ... [详细]
  • 1.如何在运行状态查看源代码?查看函数的源代码,我们通常会使用IDE来完成。比如在PyCharm中,你可以Ctrl+鼠标点击进入函数的源代码。那如果没有IDE呢?当我们想使用一个函 ... [详细]
  • CentOS7源码编译安装MySQL5.6
    2019独角兽企业重金招聘Python工程师标准一、先在cmake官网下个最新的cmake源码包cmake官网:https:www.cmake.org如此时最新 ... [详细]
  • 本文详细分析了Hive在启动过程中遇到的权限拒绝错误,并提供了多种解决方案,包括调整文件权限、用户组设置以及环境变量配置等。 ... [详细]
  • 在现代网络环境中,两台计算机之间的文件传输需求日益增长。传统的FTP和SSH方式虽然有效,但其配置复杂、步骤繁琐,难以满足快速且安全的传输需求。本文将介绍一种基于Go语言开发的新一代文件传输工具——Croc,它不仅简化了操作流程,还提供了强大的加密和跨平台支持。 ... [详细]
  • 基于KVM的SRIOV直通配置及性能测试
    SRIOV介绍、VF直通配置,以及包转发率性能测试小慢哥的原创文章,欢迎转载目录?1.SRIOV介绍?2.环境说明?3.开启SRIOV?4.生成VF?5.VF ... [详细]
  • 本文详细介绍了Linux系统中init进程的作用及其启动过程,解释了运行级别的概念,并提供了调整服务启动顺序的具体步骤和实例。通过了解这些内容,用户可以更好地管理系统的启动流程和服务配置。 ... [详细]
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社区 版权所有