为什么在setsid()之前fork()

时间:2010-04-10 10:52:58

标签: c linux system unix

为什么在fork()之前setsid()守护进程?

基本上,如果我想从其控制终端分离流程并使其成为流程组负责人:我使用setsid()

之前不做任何操作都不起作用。

为什么?

3 个答案:

答案 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冲突。