我怎么知道C程序的可执行文件是在前台还是后台运行?

时间:2010-03-11 12:57:36

标签: c linux unix solaris

在我的C程序中,我想知道我的可执行文件是否在这样的前景中运行

$./a.out

或者像这样

$./a.out &

5 个答案:

答案 0 :(得分:7)

来自Bash Reference Manual: Job Control Basics

  

后台进程是进程组ID与终端进程不同的进程;这些过程不受键盘生成的信号的影响。只允许前台进程读取或写入终端。尝试从终端读取(写入)的后台进程由终端驱动程序发送SIGTTIN(SIGTTOU)信号,除非被捕获,否则该信号暂停该进程。

因此,解决方案是为SIGTTIN安装信号处理程序,然后尝试从stdin读取(关闭缓冲或它将阻止)。如果你得到“0字节读取”,那么你就是在前台运行。

[编辑]请注意,进程的状态可能会发生变化。您可以使用shell的作业控制命令(Ctrl-Z,bgfgjobs)来执行此操作。

答案 1 :(得分:6)

如果你是前台工作,

getpgrp() == tcgetpgrp(STDOUT_FILENO)

STDIN_FILENOSTDERR_FILENO或您附加到控制终端的文件描述符。 (如果您不确定,open("/dev/tty")将始终为您的控制终端(如果存在)提供文件描述符。)

这是openssh的作用,如果您只是想快速检查,则比处理SIGTTIN/SIGTTOU更容易。

另一方面,你可能已经背景

$ ./a.out
^Z
[1]+  Stopped                 ./a.out
$ bg
[1]+ ./a.out &

或前瞻性的

$ fg
./a.out

随时都可以。您不能指望您可以检查一次,以后它仍然是真的(或错误)。

答案 2 :(得分:1)

据我所知,这是不可能的,通常也没有必要。

请解释为什么要执行此操作。

答案 3 :(得分:0)

[无效]
IIRC,getppid()(在* nix系统上)将为您提供父ID。如果为0,则“控制台”是您的父级,因此您在后台运行 [/无效]

[编辑]

int devtty;
if ((devtty = open ("/dev/tty", O_RDWR)) < 0)
   printf ("daemon\n");

请注意,这仅适用于* nix系统(并且只有在没有人删除/ dev / tty时 - 无论出于何种原因) [/编辑]

答案 4 :(得分:0)

您可能有多个流程    在后台运行:

$ jobs
[1]   Stopped                 teamviewer
[2]-  Stopped                 vim
[3]+  Stopped                 firefox
  • 使用:fg %2将vim进程发送回前台。

  • 要将最后一个流程发送回前台,只需使用:fg即可 参数。

  • 您还可以键入%process_name以恢复已停止的进程。

要暂停在后台运行的流程,请使用:

kill -19 %job_id.

-19信号是SIGSTOP(由Ctrl-Z发送的信号)。

您可以随时输入 kill -l

来查看列表

在后台/前台之间移动作业:

如果您已输入命令并忘记使用&,则可以通过键入^Z (CTRL-Z)暂停作业,然后bg,将前台作业放入后台,把它放到后台:

$ sleep 99
^Z
[1]+  Stopped                 sleep 99
$ bg
[1]+ sleep 99 &

您可以使用jobs命令列出当前shell的作业。

请记住,“退出shell”也会影响工作:

  • 当shell退出时,后台运行的作业仍在运行。
  • 终止shell退出时暂停(“已停止”)的作业。

向作业和流程发送信号

您可以使用%(JOBID)代替进程号(PID),使用作业号将信号(包括终止信号)发送到从当前shell启动的作业:

$ kill %1
[1]+  Terminated              sleep 99

要将信号发送到不是从当前shell启动的进程或作业,首先需要使用ps来查找其进程号(PID)。

您可以参考此链接: processes and jobs

Linux中的常规作业控制命令是:

  • 职位 - 列出当前职位
  • fg - 恢复队列中的下一个作业
  • fg %[number] - 恢复工作[编号]
  • bg - 将队列中的下一个作业推送到后台
  • bg %[number] - 将作业[编号]推送到后台
  • kill %[number] - 终止编号为[number]
  • 的作业
  • kill - [signal]%[number] - 将信号[signal]发送到作业号[number]
  • disown %[number] - 取消进程(不再有终端将是所有者),因此即使关闭终端后命令也会处于活动状态。

这几乎都是他们所有人。请注意命令中作业编号的%infront - 这就是告诉kill你正在谈论的是工作而不是流程。