gpt4 book ai didi

linux - 如果我们关闭启动它的终端,linux 会杀死后台进程吗?

转载 作者:IT王子 更新时间:2023-10-29 00:18:03 25 4
gpt4 key购买 nike

我有一个嵌入式系统,我在上面做 telnet然后我在后台运行一个应用程序:

./app_name &

现在,如果我关闭终端并执行 telnet从其他终端,如果我检查然后我可以看到这个过程仍在运行。

为了检查这一点,我编写了一个小程序:

#include<stdio.h>
main()
{
while(1);
}

我在后台在本地 linux pc 上运行了这个程序,然后关闭了终端。

现在,当我从其他终端检查这个进程时,我发现这个进程也被杀死了。

我的问题是:
  • 为什么相同类型的进程的未定义行为?
  • 它依赖于哪个?
  • 它依赖于Linux的版本吗?
  • 最佳答案

    谁应该杀死工作?

    通常,前台和后台作业会被 SIGHUP 杀死。在不同情况下由内核或 shell 发送。

    内核什么时候发送 SIGHUP ?

    内核发送 SIGHUPcontrolling process :

  • 对于真实(硬件)终端:当在终端驱动程序中检测到断开连接时,例如调制解调器线路挂断时;
  • pseudoterminal (pty):当最后一个引用 pty 主端的描述符关闭时,例如当您关闭终端窗口时。

  • 内核发送 SIGHUP到其他进程组:
  • 当控制进程终止时,将进程组置于前台;
  • orphaned process group ,当它成为孤儿并停止成员时。

  • Controlling process is the session leader that established the connection to the controlling terminal.



    通常,控制进程是您的 shell。所以,总结一下:
  • 内核发送 SIGHUP当真实或伪终端断开/关闭时到 shell ;
  • 内核发送 SIGHUP当 shell 终止时将进程组置于前台;
  • 内核发送 SIGHUP如果孤立进程组包含已停止的进程,则发送到孤立进程组。

  • 注意内核不发送 SIGHUP如果它不包含停止的进程,则到后台进程组。

    什么时候开始 bash发送 SIGHUP ?

    Bash 发送 SIGHUP到所有工作(前台和后台):
  • 当它收到 SIGHUP , 它是一个交互式 shell(并且在编译时启用了作业控制支持);
  • 当它退出时,它是一个交互式登录shell,和huponexit选项已设置(并且在编译时启用作业控制支持)。

  • 查看更多详情 here .

    笔记:
  • bash不送SIGHUP使用 disown 从工作列表中删除的工作;
  • 进程开始使用 nohup忽略 SIGHUP .

  • 更多详情 here .

    其他 shell 呢?

    通常,shell 会传播 SIGHUP .正在生成 SIGHUP在正常导出不太常见。

    远程登录或 SSH

    在 telnet 或 SSH 下,连接关闭时会发生以下情况(例如,当您关闭 PC 上的 telnet 窗口时):
  • 客户被杀;
  • 服务器检测到客户端连接已关闭;
  • 服务器关闭 pty 的主端;
  • 内核检测到 master pty 已关闭并发送 SIGHUPbash ;
  • bash接收 SIGHUP , 发送 SIGHUP到所有工作并终止;
  • 每个作业接收 SIGHUP并终止。


  • 问题

    我可以使用 bash 重现您的问题和 telnetd来自 busyboxdropbear SSH 服务器:有时,后台作业没有收到 SIGHUP (并且不会终止)当客户端连接关闭时。

    好像是 竞争条件 当服务器( telnetddropbear )关闭 pty 的主端时发生:
  • 通常,bash接收 SIGHUP并立即终止后台作业(如预期)并终止;
  • 但有时,bash检测 EOF在处理之前在 pty 的从属端 SIGHUP .

  • bash检测 EOF ,默认情况下会立即终止而不发送 SIGHUP .后台作业仍在运行!

    解决方案

    可以配置 bash发送 SIGHUP在正常退出(包括 EOF )时:
  • 确保 bash作为登录 shell 启动。 huponexit works仅适用于登录 shell ,AFAIK。

    登录 shell 由 -l 启用选项或 leading hyphenargv[0] .您可以配置 telnetd运行 /bin/bash -l或更好 /bin/login调用 /bin/sh在登录 shell 模式下。

    例如。:

    telnetd -l/bin/登录
  • 启用 huponexit选项。

    例如。:

    shopt -s huponexit

    bash 中输入此内容session 每次或添加到 .bashrc/etc/profile .


  • 为什么会出现赛跑?
    bash只有在安全时才解除阻塞信号,并在某些代码部分不能被信号处理程序安全中断时阻塞它们。

    这样的临界区会不时调用中断点,如果在临界区执行时收到信号,它的处理程序将延迟到下一个中​​断点发生或临界区退出。

    您可以从 quit.h 开始挖掘在源代码中。

    因此,似乎在我们的案例中 bash有时会收到 SIGHUP当它处于临界区时。 SIGHUP处理程序执行被延迟,并且 bash阅读 EOF并在退出临界区或调用下一个中断点之前终止。

    引用
  • "Job Control" Glibc 官方手册中的部分。
  • “Linux 编程接口(interface)”一书的第 34 章“进程组、 session 和作业控制”。
  • 关于linux - 如果我们关闭启动它的终端,linux 会杀死后台进程吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32780706/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com