3

当我fork()在 C on 中执行 a 时Linux,新创建的子进程是前台进程还是后台进程?

如果默认是前台,有没有办法强制将其创建为后台进程?

我阅读了很多关于 的链接fork,但无论是前景还是背景,都没有在任何地方提及。

http://en.wikipedia.org/wiki/Fork_(system_call)

http://linux.die.net/man/2/fork

http://www.csl.mtu.edu/cs4411.ck/www/NOTES/process/fork/create.html

4

3 回答 3

2

只需使用我在下面详述的命令将序列设置为背景或前景。使用pid = fork()确保您在父或子中执行您想要首先设置的任何一个。在父进程中,pid 将是子进程的 PID,在子进程中为 0。像这样使用它:

if(pid)
// Parent
else
// Child

过程

进程 pid 被放入进程组 pgid 通过

setpgid(pid, pgid);

如果 pgid == pid 或 pgid == 0 那么这将创建一个具有进程组领导 pid 的新进程组。否则,这会将 pid 放入已经存在的进程组 pgid。零 pid 指的是当前进程。调用 setpgrp() 等效于 setpgid(0,0)。

前景

在一个会话的进程组中,最多可以有一个是该会话的前台进程组。tty 输入和 tty 信号(由 ^C、^Z 等生成的信号)进入此前台进程组中的进程。

进程可以使用 tcgetpgrp(fd) 确定其会话中的前台进程组,其中 fd 指的是其控制 tty。如果没有,这将返回一个大于 1 的随机值,它不是进程组 ID。

进程可以使用 tcsetpgrp(fd,pgrp) 设置其会话中的前台进程组,其中 fd 指的是其控制 tty,而 pgrp 是其会话中的一个进程组,并且该会话仍然与该会话的控制 tty 相关联调用过程。

一个人如何得到fd?根据定义,/dev/tty 指的是控制 tty,完全独立于标准输入和输出的重定向。(还有函数 ctermid() 来获取控制终端的名称。在 POSIX 标准系统上,它将返回 /dev/tty。)打开控制终端的名称会给出一个文件描述符 fd。

背景

会话中所有非前台进程组的进程组都是后台进程组。由于键盘上的用户正在与前台进程交互,因此后台进程应该远离它。当后台进程从终端读取数据时,它会收到一个 SIGTTIN 信号。通常,这将停止它,作业控制外壳通知并告诉用户,谁可以说 fg 继续这个后台进程作为前台进程,然后这个进程可以从终端读取。但是如果后台进程忽略或阻塞了 SIGTTIN 信号,或者如果它的进程组是孤立的(见下文),那么 read() 会返回一个 EIO 错误,并且不会发送任何信号。(实际上,这个想法是告诉进程现在不允许从终端读取。如果它看不到信号,那么它将看到错误返回。)

当后台进程写入终端时,它可能会收到一个 SIGTTOU 信号。可能:即设置必须发生这种情况的标志时(默认为关闭)。可以通过设置标志

% stty tostop

并再次清除它

% stty -tostop

并通过以下方式检查

% stty -a
于 2015-05-27T08:29:16.323 回答
0

在 Linux 和许多类似 Unix 的系统上,您可能希望使用daemon(3)创建后台的守护进程。

您可能还想使用dup2(2)关闭 (2)或重定向所有stdinstdoutstderr(可能到/dev/null,参见null(4) ) 。

否则,请注意控制终端进程组作业控制、会话 ID。请参阅setpgrp(2)(和setpgid)和NOTES部分。使用tcsetpgrp(3) , setsid(2)

另请阅读tty 揭秘页面 && tty(4)

于 2015-05-27T08:33:32.590 回答
0

您是否正在尝试更改代码中的nice值?每当您分叉一个进程时,它都在“后台”中。取决于你的意思,以及你想要做什么。

于 2015-05-27T08:43:29.320 回答