代码之家  ›  专栏  ›  技术社区  ›  Tim unnamed eng

setpgid()的第一个参数可以是会话领队还是组领队?

  •  2
  • Tim unnamed eng  · 技术社区  · 7 年前

    从Linux编程界面

    #include <unistd.h>
    int setpgid(pid_t  pid , pid_t  pgid );
    

    pid参数不能指定作为会话主持人的进程。违反 这条规则会导致错误eperm。

    1. 为什么不能 pid 成为会议领导人?
    2. 罐头 PID 做一个组长,为什么?

      如果是,在呼叫后 setpgid() ,在哪个组中,最初在组中的其他进程 最初由流程领导 PID 铍:

      • 其gid为的原始组 PID PID 没有组长,或者
      • 新团体 pgid 哪个过程 PID 更改为?

      我怀疑第一个可能与这本书描述的相矛盾。 setsid() :

      对能够调用setsid()的流程组负责人的限制是必要的,因为没有它,流程组负责人就能够将自己放入另一个(新)会话,而流程组的其他成员仍留在原始会话中。( 不会创建新的流程组,因为根据定义,流程组负责人流程组ID已经与其流程ID相同。 )这将违反会话和流程组的严格的两级层次结构,其中流程组的所有成员必须是同一会话的一部分。

    谢谢。

    一些相关问题 Can a leader of a process session or group leave for another existing session or group?

    2 回复  |  直到 7 年前
        1
  •  2
  •   zwol    7 年前

    这个行为是由posix指定的(这意味着它适用于称自己为“unix”的所有东西,而不仅仅是linux)。 http://pubs.opengroup.org/onlinepubs/9699919799/functions/setpgid.html 说:

    ERRORS
        [EPERM] The process indicated by the pid argument is a session leader.
    

    规范没有说明这个规则存在的原因,但我相信dbush声明的基本原理是正确的:a 阶段 leader必须始终是流程组的leader;如果它可以移动到另一个流程组,它将不再是流程组的leader,这违反了不变量。

    然而,一个过程只是一个过程小组的领导者,而不是一个会话的领导者, 可以 将自己放入另一个流程组(不再是流程组负责人),然后可能将自己从流程组中拉出来,再次成为流程组负责人。实际上,作业控制外壳 在某些情况下这样做:注意规范基本原理部分底部的位

    setpgid()的一个不明显的用途是允许作业控制shell返回到其原始进程组(执行作业控制shell时生效的进程组)。作业控件shell在终止或挂起自身以将其作业控件“状态”还原回其父控件所期望的状态时,会在将控件返回其父控件之前执行此操作。

    posix没有解释为什么作业控制shell会首先更改其进程组,但是 GNU C Library manual section on implementing job control 填补空白:

    当一个通常执行作业控制的shell程序启动时,必须小心,以防它被另一个已经在执行自己作业控制的shell调用。

    交互运行的子shell必须确保它在启用作业控制本身之前已被其父shell放置在前台。

    […]

    一旦子shell被其父shell放入前台,它就可以启用自己的作业控制。它是通过打电话 setpgid 把自己放入自己的进程组,然后调用 tcsetpgrp 将此进程组放入前台。

    当然,如果子shell被挂起(例如bash有一个 suspend 这样做的内置)。

    还请注意,作业控件外壳程序 使自己成为 阶段 领袖,即使它不是任何东西的子地狱。会话由负责设置控制终端的任何程序初始化;该程序通常是父程序和预程序- exec 终端中运行的最外层外壳的标识。例如, xterm calls setsid 在打开假终端和分叉之后,但在 执行程序 -在终端窗口中运行的程序。

        2
  •  2
  •   dbush    7 年前

    会议领导人总是一个过程小组领导人。如果您要将其移动到另一个流程组,它将不再是流程组负责人,这违反了前面的规则。