请告诉我进程组ID和jobid之间的区别。 jobid是内置的shell程序还是与内核相关?他们每个人的用途是什么?当进程在后台运行时,只设置jobid或者是否设置了pgid? setpgid()函数有什么用途?
当进程在后台运行时,内核是否也参与其中,或者shell是否负责后台或前台?
答案 0 :(得分:13)
好问题。作业ID主要只是一个shell构造。内核中支持作业控制中涉及的信号形式,以及内核确切地知道将作业控制信号发送到哪些进程的方式。
严格地说,第一个问题的答案是作业ID纯粹是一个shell创建。它之所以存在是因为管道(或很少是另一个shell分组构造)可能由多个应该由一个单元控制的进程组成。
要回答您的上一个问题,shell首先执行fork(2)
然后执行execve(2)
来启动所有进程。与&
的唯一区别在于shell不执行wait(2)
(或相关变体),因此程序可以“在后台”继续。 Unix在前景和后台之间几乎没有什么区别。
进程组是由shell定义的关联,以便内核知道处理一组各种“后台”进程的单个“前台”进程。这一点非常重要,因为如果他们决定突然从终端读取,后台进程将生成一个信号。 (这样的终端可能连接到标准输入。)这将导致“作业”生成一个信号,shell将提示用户做某事。
尝试(sleep 5; read x)&
并在6秒后键入一个返回或其他内容,以便shell唤醒。那是你看到像......的时候。
[1] +停止(睡5;读x)
...然后输入fg
将其拉到前台。
最初,Unix有管道,它有&
,但没有办法在前台和后台之间移动命令或管道,也无法帮助突然决定读取标准输入的后台进程。< / p>
Bill Joy和其他人在早期版本的BSD和csh(1)中添加了作业控制及其内核支持。这些是通过商业Unix逐行获取的,并克隆到类似工作的Linux内核中。
关于流程组和ps(1)
的问题......
为了支持shell中的作业控制,内核进程状态包括进程组ID和会话ID。 进程组和作业是相同的,但作业号只是shell组成的句柄。如果会话ID与pid相同,则进程是会话负责人,如果pgid与pid相同,则进程是进程组负责人。我相信+
打印的ps(1)
会发生一些更微妙的事情。每个终端都知道它的前台进程组是什么,所以我相信一个进程得+ +如果pid == pgid&amp;&amp; (pgid是其控制终端的前景pg。)
总之,内核保留了几个状态项:pid,pgid,sid,进程可能有一个控制终端,终端可能有一个前台pgid。这些凭据主要用于支持作业控制,但也用于在用户注销时撤消对终端的访问。