Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何知道C程序';s的可执行文件是在前台还是后台运行?_C_Linux_Unix_Solaris - Fatal编程技术网

如何知道C程序';s的可执行文件是在前台还是后台运行?

如何知道C程序';s的可执行文件是在前台还是后台运行?,c,linux,unix,solaris,C,Linux,Unix,Solaris,在我的C程序中,我想知道我的可执行文件是否像这样在前台运行 $./a.out $./a.out & 还是像这样 $./a.out $./a.out & 据我所知,这是不可能的,通常也没有必要 请解释为什么要这样做。[invalid]IIRC,getppid()(在*nix系统上)将为您提供父id。如果是0,则“控制台”是您的父id,因此您正在后台运行。 [/无效] [编辑] int devtty; if ((devtty = open ("/dev/tty", O_RDW

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

$./a.out
$./a.out &
还是像这样

$./a.out
$./a.out &

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

请解释为什么要这样做。

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

[编辑]

int devtty;
if ((devtty = open ("/dev/tty", O_RDWR)) < 0)
   printf ("daemon\n");
int-devty;
如果((devtty=open(“/dev/tty”,O_RDWR))<0)
printf(“守护程序”\n);

请注意,这仅在*nix系统上有效(并且仅当没有人删除/dev/tty时——无论出于何种原因)
[/edit]

来自:

后台进程是进程组id与终端不同的进程;这些过程对键盘产生的信号免疫。只允许前台进程读取或写入终端。试图读取(写入)终端的后台进程由终端驱动程序发送一个SIGTTIN(SIGTTOU)信号,除非被捕获,否则将暂停进程

因此,解决方案是为
SIGTTIN
安装一个信号处理程序,然后尝试从
stdin
读取数据(关闭缓冲,否则它将阻塞)。如果返回“0字节读取”,则在前台运行


[编辑]请注意,进程的状态可能会更改。您可以使用shell的作业控制命令(Ctrl-Z、
bg
fg
jobs
)来执行此操作。

如果您是前台作业

getpgrp() == tcgetpgrp(STDOUT_FILENO)
或者
STDIN_FILENO
STDERR_FILENO
或通过任何文件描述符连接到控制终端。(如果您不确定,
open(“/dev/tty”)
将始终为您的控制终端(如果存在)提供一个文件描述符。)

这就是它的作用,如果您只想快速检查,那么它比处理
SIGTTIN/sigttoo
要简单一些

另一方面,你可能有背景

$ ./a.out ^Z [1]+ Stopped ./a.out $ bg [1]+ ./a.out & 美元/年 ^Z [1] 停止 $bg [1] +./a.out& 还是前景化

$ fg ./a.out $fg /a.out
在任何时间点。您不能期望您可以检查一次,以后它仍然是真的(或假的)。

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

$ jobs
[1]   Stopped                 teamviewer
[2]-  Stopped                 vim
[3]+  Stopped                 firefox
$ sleep 99
^Z
[1]+  Stopped                 sleep 99
$ bg
[1]+ sleep 99 &
  • 使用:
    fg%2
    将vim进程发送回前台

  • 要将最后一个进程发送回前台,只需使用:
    fg
    ,不带 争论

  • 您还可以键入%process\u name来恢复已停止的进程
要暂停在后台运行的进程,请使用:

kill -19 %job_id.
-19
信号是SIGSTOP(由Ctrl-Z发送的信号)

通过键入
kill-l

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

如果您已键入命令,但忘记使用
&
,则可以通过键入
^Z(CTRL-Z)
暂停作业,然后键入
bg
,将其置于后台,将前台作业置于后台:

$ jobs
[1]   Stopped                 teamviewer
[2]-  Stopped                 vim
[3]+  Stopped                 firefox
$ sleep 99
^Z
[1]+  Stopped                 sleep 99
$ bg
[1]+ sleep 99 &
您可以使用
jobs
命令列出当前shell的作业

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

  • shell出口保持运行时在后台运行的作业
  • 外壳程序退出终止时暂停(“停止”)的作业
向作业和进程发送信号

您可以使用作业编号(使用%(JOBID)而不是进程编号(PID),将信号(包括终止信号)发送到从当前外壳启动的作业:

要向未从当前shell启动的进程或作业发送信号,首先需要使用
ps
查找它们的进程号(PID)

您可以参考此链接:

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

  • 作业-列出当前作业
  • fg-恢复队列中下一个作业
  • fg%[number]-恢复工作[number]
  • bg-将队列中的下一个作业推送到后台
  • bg%[number]-将作业[number]推到后台
  • 终止%[number]-终止编号为[number]的作业
  • kill-[signal][number]-将信号[signal]发送到作业编号[number]
  • disown%[number]-断开进程的连接(不再拥有任何终端),因此即使在关闭终端后,命令仍将处于活动状态

差不多都是这样。请注意命令中作业编号前面的百分比-这就是告诉kill您谈论的是作业而不是进程的原因。

记住,程序可以根据用户的意愿在fg和bg之间切换(在bash:ctrl-z中暂停fg进程,
bg
在bg中运行的命令,可以移回fg,等等)。@Roger Pate:SIGTSTP是POSIX,蒂姆:我试着说出这个例子,这样它就不会被误解,而不是尽可能的笼统。为什么投票要结束呢?这绝对是一个C问题。无法用示例程序重现此问题。getppid()为“/a.out”和“/a.out&”返回了相同的值。我怀疑getppid()能否返回0。它要么返回1(如果您与控制台分离,并且内核使您成为init进程的子进程),要么返回启动您的bash shell的PID。
/dev/tty
即使在后台也可以打开,只要你还有一个控制终端。假设我的进程正在做一个进程密集型的工作,并且想要打印一个类似状态栏的东西,直到通过SIGALRM的信号处理器打印“#”完成计算。如果我的进程在后台运行,我不想打印“#”。Tha