C/C++进程如何知道它是否在后台运行?

4

我在我的进程中有一个方法,只有当该进程不在后台运行时才应该运行。如何动态测试当前进程是否在后台运行?谢谢


3
当您说“background”时,您是指*nix进程意义上的背景还是GUI界面意义上的背景? - Paul R
您的标题措辞对我来说毫无意义。C和C++是编程语言,而不是Unix进程的属性。 - Jens Gustedt
4个回答

7

以下是我在使用带作业控制的终端程序时所用的方法(大多数终端都适用,详见下文):

/* We can read from stdin if :
 * - we are in foreground
 * - stdin is a pipe end
 */
static int validate_stdin(void) {
    pid_t fg = tcgetpgrp(STDIN_FILENO);
    int rc = 0;
    if(fg == -1) {
        debug_printf("Piped\n");
    }  else if (fg == getpgrp()) {
        debug_printf("foreground\n");
    } else {
        debug_printf("background\n");
        rc = -1;
    }
    return rc;
}

如果会话有一个控制终端,则前台只能有一个进程组,并且tcget/setpgrp用于设置此进程组ID。因此,如果您的进程组ID不是前台进程组ID,则您不在前台。
如果shell具有作业控制功能,则像mouviciel所指出的那样可以工作。但是,这并不总是情况。例如,在使用busybox的嵌入式系统上,shell可以配置为具有或不具有作业控制功能。

4

请查看Unix常见问题解答:如何检测进程是否在后台运行?

一般的回答是:你无法确定自己是否在后台运行。

但是,你可以检查stdin是否为终端:if(isatty(0)) { ... }


从您的链接中,一般的答案是取决于您是否拥有带作业控制的 shell。现在,这已经成为相当标准的行为。 - shodanex
由于我从事嵌入式系统工作,我从不认为这是理所当然的。但在一般情况下,你是正确的。 - mouviciel

0

这与在后台运行某些东西有什么关系?DISPLAY变量是X的一部分,与进程控制无关。 - Noufal Ibrahim

0

这听起来像是一个糟糕的设计。你能告诉我们一些关于你在问题中提到的方法的信息吗?正如mouviciel所说,没有可靠的方法。

我有一个建议,就是默认使用“前台行为”,并将“后台行为”保留在类似-d(守护进程模式)的开关下,或者反之亦然,如果您的程序通常在后台运行。这种用法的一个例子是fetchmail


为什么是-1?为什么人们这样做却不说原因?知道原因会有帮助的。 - Noufal Ibrahim

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接