查明进程是否在后台启动或在运行中进入后台

查明进程是否在后台启动或在运行中进入后台

我对 Linux 特别感兴趣,但对于其他 Unices 的答案也很好:系统是否有一种方式向进程发出信号,表明它已在后台启动?换句话说,是否有一个我可以捕获的信号,或者我可以从 Bash/Perl/Python 脚本或类似脚本中检查的信号,以告诉我该脚本在启动时是否处于后台?

答案1

在这种情况下,“背景”有多种可能的含义。

这可能意味着它没有控制终端。 (例如,某些内容是从 cron、systemd 或 init 启动的)。

如果它不仅进入后台,而且从其父进程 ( getppid) 中孤立出来,则其父进程的 pid 将为 1。无论是否有控制终端,都可能发生这种情况。

如果进程有控制终端,则它可以位于前台或后台。

如果进程位于前台,则getpgrptcgetpgrp函数将返回相同的值(假设 tcgetpgrp 被赋予控制终端的文件描述符——例如 2=stderr)。

如果一个进程在后台,getpgrp将会tcgetpgrp返回不同的数字。

如果进程位于前台并且停止,它将收到信号 SIGSTOP 或 SIGTSTP 之一。请注意,SIGSTOP 无法被捕获,如果您捕获 SIGTSTP,它将阻止您的作业被停止。

当您的进程从停止状态恢复时,您会收到信号 SIGCONT,之后您可以检查您是在前台还是后台。

如果一个进程位于后台并被带到前台,我认为它不会收到任何信号,但上述检查仍然有效。

如果一个进程位于后台并尝试输入或(可能)输出,您将(分别)获得 SIGTTIN 或 SIGTTOU,您可以捕获它们。

以上对于 POSIX 系统是正确的,它涵盖了 linux 和大多数 unix 系统。

请注意,如果您的程序位于管道中间,则 stdin 和 stdout 将不是控制终端(或者如果其中一个位于管道的任一端,则它不会是控制终端)。另外,stderr 也可以被重定向(但这不太可能)。您可以通过打开来获取控制终端/dev/tty(如果没有,则会失败),但这是不可移植的。 (不知道有没有更好的办法。)

相关内容