UNIX 中进程组 ID 和作业 ID 的区别
请告诉我进程组 ID 和 jobid 之间的区别。 jobid是shell程序的内置函数还是与内核相关?它们各自的用途是什么?当进程在后台运行时,是仅设置 jobid 还是同时设置 pgid? setpgid()函数有什么用?
当一个进程在后台运行时,内核是否也参与其中,或者 shell 是否负责后台或前台?
Please tell me the difference between a process group ID and a jobid. Is jobid a builtin of a shell program or is it related to the kernel? What are the uses of each of them? When a process is run in background, is only jobid set or is the pgid set as well?
What are the uses of the setpgid() function?
When a process is run in background, is the kernel also involved or does the shell take care of which is background or foreground?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
好问题。作业 ID 主要只是一个 shell 结构。内核中以作业控制中涉及的信号的形式提供支持,以及内核确切地知道将作业控制信号发送到哪些进程的方式。
严格来说,第一个问题的答案是,job id 纯粹是 shell 创建的。它的存在是因为管道(或者很少是另一个 shell 分组构造)可能由多个进程组成,这些进程应作为一个单元进行控制。
为了回答您的最后一个问题,shell 首先执行
fork(2)
然后执行execve(2)
来启动所有进程。与&
的唯一区别是 shell 不执行wait(2)
(或相关变体),因此程序可以“在后台”继续运行。实际上,Unix 中前台和后台之间几乎没有区别。进程组是由 shell 定义的关联,以便内核了解处理一组各种“后台”进程的单个“前台”进程。这非常重要,这样后台进程如果决定突然从终端读取数据,就会生成一个信号。 (这样的终端可能连接到标准输入。)这将导致“作业”生成一个信号,并且 shell 将提示用户执行某些操作。
尝试
(sleep 5; read x)&
并在 6 秒后键入 return 或其他内容,以便唤醒 shell。那时你会看到类似......然后输入
fg
将其拉入前台。最初,Unix 有管道,并且有
&
,但是没有办法在前台和后台之间移动命令或管道,也没有办法帮助突然决定读取标准输入的后台进程。Bill Joy 和其他人在 BSD 和 csh(1) 的早期版本中添加了作业控制及其内核支持。这些被商业 Unix 逐行选取并克隆为类似工作的 Linux 内核。
关于进程组和
ps(1)
的问题...为了支持shell中的作业控制,内核进程状态包括进程组ID和会话ID。 进程组和作业是同一件事,但作业编号只是shell组成的句柄。如果会话 ID 与 pid 相同,则进程为会话领导者;如果 pgid 与 pid 相同,则进程为进程组领导者。我相信
ps(1)
打印的+
正在发生一些更微妙的事情。每个终端都知道它的前台进程组是什么,所以我相信如果 pid == pgid && ,进程会得到 + (pgid 是其控制终端的前台 pg)。总之,内核保存了几个状态项:pid、pgid、sid,并且一个进程可能有一个控制终端,一个终端可能有一个前台pgid。这些凭据主要用于支持作业控制,但也用于在用户注销时撤销对终端的访问权限。
Good questions. The job id is mostly just a shell construct. There is support in the kernel in the form of the signals that are involved in job control, and the way in which the kernel knows exactly which processes to send the job control signals to.
Strictly speaking, the answer to your first question is that the job id is purely a shell creation. It exists because a pipeline (or, rarely, another shell grouped construct) may consist of multiple processes that should be controlled as a unit.
To answer your last question, the shell starts all processes by first doing a
fork(2)
and then doing anexecve(2)
. The only difference with&
is that the shell does not do await(2)
(or a related variant) and so the program can continue "in the background". There is actually little distinction in Unix between foreground and background.The process group is an association defined by shells so that the kernel knows about a single "foreground" process that handles a set of various "background" processes. This is mainly important so that the background processes will generate a signal should they decide to suddenly read from a terminal. (Such terminal probably being connected to standard input.) This will cause the "job" to generate a signal and the shell will prompt the user to do something.
Try
(sleep 5; read x)&
and after 6 seconds type a return or something so that the shell wakes up. That's when you see something like......and you then type
fg
to pull it into the foreground.Originally, Unix had pipelines, and it had
&
, but there was no way to move a command or pipeline between foreground and background and no way to help a background process that suddenly decided to read standard input.Job control and the kernel support for it were added by Bill Joy and others in early versions of BSD and csh(1). These were picked up line-for-line by commercial Unix and in cloned for the work-alike Linux kernel.
Regarding the questions about process groups and
ps(1)
...In order to support job control in shells, the kernel process state includes a process group ID and a session ID. A process group and a job are the same thing, but a job number is just a handle the shell makes up. A process is a session leader if the session ID is the same as the pid, and a process is a process group leader if the pgid is the same as the pid. I believe something a bit more subtle is happening with the
+
thatps(1)
prints. Each terminal knows what its foreground process group is, so I believe a process gets a + if pid == pgid && (pgid is the foreground pg for its controlling terminal).In summary, the kernel keeps several items of state: pid, pgid, sid, and a process may have a controlling terminal and a terminal may have a foreground pgid. These credentials are mostly intended to support job control but are also used to revoke access to a terminal when a user logs out.