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

发布于 2024-08-24 17:29:48 字数 123 浏览 4 评论 0原文

在前台运行

$./a.out

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

$./a.out &

In my C program I want to know if my executable is run in foreground like this

$./a.out

or like this

$./a.out &

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

回心转意 2024-08-31 17:29:48

如果您是前台作业,

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

在任何时间点 。你不能期望你检查一次之后它仍然是正确的(或错误的)。

If you are the foreground job,

getpgrp() == tcgetpgrp(STDOUT_FILENO)

or STDIN_FILENO or STDERR_FILENO or whichever file descriptor you're attached to your controlling terminal by. (If you're not sure, open("/dev/tty") will always get you a file descriptor to your controlling terminal, if one exists.)

This is what openssh does, and is a bit easier than handling SIGTTIN/SIGTTOU if you just want a quick check.

On the other hand, you may have been backgrounded

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

or foregrounded

$ fg
./a.out

at any point in time. You cannot expect that you can check this once and it will still be true (or false) later.

允世 2024-08-31 17:29:48

来自 Bash 参考手册:作业控制基础知识

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

因此,解决方案是为 SIGTTIN 安装信号处理程序,然后尝试从 stdin 读取(关闭缓冲,否则会阻塞)。如果返回“0 bytes read”,则表明您正在前台运行。

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

From the Bash Reference Manual: Job Control Basics:

Background processes are those whose process group id differs from the terminal's; such processes are immune to keyboard-generated signals. Only foreground processes are allowed to read from or write to the terminal. Background processes which attempt to read from (write to) the terminal are sent a SIGTTIN (SIGTTOU) signal by the terminal driver, which, unless caught, suspends the process.

So the solution is to install a signal handler for SIGTTIN and then try to read from stdin (turn buffering off or it will block). If you get "0 bytes read" back, then you're running in the foreground.

[EDIT] Note that the status of a process can change. You can use the job control commands of the shell (Ctrl-Z, bg, fg and jobs) to do this.

如梦亦如幻 2024-08-31 17:29:48

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

请解释您为什么要这样做。为什么

To my knowledge this is not possible and usually not necessary either.

Please explain why you want to do this.

赢得她心 2024-08-31 17:29:48

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

[编辑]

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

请注意,这仅在 *nix 系统上有效(并且只有在没有人删除 /dev/tty 的情况下——无论出于何种原因)
[/编辑]

[invalid]
IIRC, getppid() (on *nix systems) will give you the parent id. if it is 0, the 'console' is your parent and so you are running in the background.
[/invalid]

[edit]

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

note that this is only valid on *nix systems (and then only if nobody has deleted /dev/tty -- for whatever reason)
[/edit]

∝单色的世界 2024-08-31 17:29:48

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

$ 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)。

您可以参考这个链接:
进程和作业

Linux 中的一般作业控制命令是:

  • jobs - 列出当前作业
  • fg - 恢复队列中的下一个作业
  • fg %[number] - 恢复作业 [number]
  • bg< /strong> - 将队列中的下一个作业推送到后台
  • bg %[number] - 将作业 [number] 推送到后台
  • kill %[number] - 杀死编号为 [number] 的作业
  • kill -[signal] %[number] - 将信号 [signal] 发送到作业编号 [number]
  • disown %[number] - 否认进程(不再有终端将成为所有者),因此即使关闭终端后命令仍然有效。

这几乎就是全部了。请注意命令中作业编号前面的 % - 这就是告诉kill您正在谈论作业而不是进程的原因。

There may be a possibility that you have more than one process
running in the background:

$ jobs
[1]   Stopped                 teamviewer
[2]-  Stopped                 vim
[3]+  Stopped                 firefox
  • use: fg %2 to send the vim process back to foreground.

  • To send the last process back to foreground simply use: fg with no
    arguments.

  • You can also type % process_name to resume the stopped process.

To suspend the process running in the background, use:

kill -19 %job_id.

The -19 signal is SIGSTOP (the signal sent by Ctrl - Z) .

you can always see the list by typing kill -l

Moving jobs between background / foreground:

If you have already typed a command and forgot to use the &, you can put a foreground job into the background by typing ^Z (CTRL-Z) to suspend the job, followed by bg, to put it into the background:

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

You can list the jobs of the current shell using the jobs command.

Just remember that "exiting shell" affects jobs as well:

  • Jobs running in the background when the shell exits are left running.
  • Jobs that are paused (“Stopped”) when the shell exits are terminated.

Sending signals to jobs and processes

You can send signals, including termination signals, to jobs that are started from the current shell using job numbers using %(JOBID) instead of process numbers(PID):

$ kill %1
[1]+  Terminated              sleep 99

To send signals to processes or jobs that are not started from the current shell, you first need to use ps to find their process numbers(PID).

You can refer to this link:
processes and jobs

The general job control commands in Linux are:

  • jobs - list the current jobs
  • fg - resume the job that's next in the queue
  • fg %[number] - resume job [number]
  • bg - Push the next job in the queue into the background
  • bg %[number] - Push the job [number] into the background
  • kill %[number] - Kill the job numbered [number]
  • kill -[signal] %[number] - Send the signal [signal] to job number [number]
  • disown %[number] - disown the process(no more terminal will be owner), so command will be alive even after closing the terminal.

That's pretty much all of them. Note the % infront of the job number in the commands - this is what tells kill you're talking about jobs and not processes.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文