为什么在fork()
之前setsid()
守护进程?
基本上,如果我想从其控制终端分离流程并使其成为流程组负责人:我使用setsid()
。
之前不做任何操作都不起作用。
为什么?
答案 0 :(得分:52)
首先:setsid()会使您的流程成为流程组的领导者,但它也会使您成为新会话的领导者。如果您只想获得自己的进程组,请使用setpgid(0,0)。
现在了解setsid()返回EPERM的实际原因如果您已经是流程组负责人或会话负责人,您必须了解流程组和会话ID是从创建它们的流程的流程ID初始化的(因此导致它们,即对于会话领导者pid == sid和进程组领导者pid == pgid)。进程组也无法在会话之间移动。
这意味着如果您是流程组负责人,并且允许创建新会话,那么sid和pgid将设置为您的pid,使旧流程组中的其他流程处于奇怪的状态:他们的流程小组长突然处于不同的会话中,然后他们自己可能会。并且这是不允许的,因此内核的EPERM。
现在如果你fork()一旦既不是会话也不是进程组长,那么将你的sid和pgid设置到你的pid是安全的,因为这样的组中没有其他进程。
所以,yepp,想一想,这一切都有道理。
答案 1 :(得分:18)
需要fork()
并让孩子致电setsid()
以确保调用setsid()
的流程不是流程组负责人(setsid()
想要制作调用进程是 new 进程组的进程组负责人,因此在这种情况下失败了。)
答案 2 :(得分:2)
man 2 setsid
,您将获得以下说明:
如果调用进程不是进程组负责人,setsid()会创建一个新会话。调用进程是新会话的领导者,新进程组的进程组负责人,并且没有控制终端。调用进程的进程组ID和会话ID被设置为调用进程的PID。调用进程将是此新进程组和此新会话中的唯一进程。
如果允许流程组负责人调用setsid()
,则创建新会话和新流程组(具有相同的流程组ID),这将导致流程组ID冲突。