C语言 为什么在 setsid() 之前 fork()

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2613104/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 05:08:34  来源:igfitidea点击:

Why fork() before setsid()

clinuxsystemunix

提问by cerisier

Why fork()before setsid()to daemonize a process?

为什么fork()之前setsid()以守护进程的过程?

Basically, if I want to detach a process from its controlling terminal and make it a process group leader : I use setsid().

基本上,如果我想将一个进程与其控制终端分离并使其成为进程组领导:我使用setsid().

Doing this without forking before doesn't work.

在没有分叉之前这样做是行不通的。

Why?

为什么?

回答by user175104

First of all: setsid() will make your process a process group leader, but it will also make you the leader of a new session. If you are just interested in getting your own process group, then use setpgid(0,0).

首先:setsid() 将使您的流程成为流程组的领导者,但它也会使您成为新会话的领导者。如果您只是想获得自己的进程组,请使用 setpgid(0,0)。

Now for understanding the actual reason why setsid() returns EPERM if you already are process group leader or session leader you have to understand that process group and session ids are initialized from the process id of the process creating them (and hence leading them, i.e. for a session leader pid == sid and for a process group leader pid == pgid). Also process groups cannot move between sessions.

现在要了解如果您已经是流程组领导或会话领导,setsid() 返回 EPERM 的实际原因,您必须了解流程组和会话 ID 是从创建它们的流程的进程 ID 初始化的(并因此引导它们,即对于会话领导 pid == sid 和进程组领导 pid == pgid)。进程组也不能在会话之间移动。

That means if you are a process group leader, and creating a new session would be allowed then the sid and the pgid would get set to your pid, leaving the other processes in your old process group in a weird state: their process group leader suddenly is in a different session then they themselves might be. And that cannot be allowed, hence the EPERM by the kernel.

这意味着如果您是进程组组长,并且允许创建新会话,那么 sid 和 pgid 将设置为您的 pid,使旧进程组中的其他进程处于一种奇怪的状态:他们的进程组组长突然是在不同的会话中,那么他们自己可能是。这是不允许的,因此内核使用 EPERM。

Now if you fork() once you are neither session nor process group leader anymore and hence setting your sid and pgid to your pid is safe, because there are no other processes in such group.

现在,如果你 fork() 一旦你既不是会话也不是进程组组长,因此将你的 sid 和 pgid 设置为你的 pid 是安全的,因为这样的组中没有其他进程。

So, yepp, think about it, it all makes sense.

所以,是的,想想看,这一切都说得通。

回答by caf

It is required to fork()and have the child call setsid()to ensure that the process calling setsid()isn't already a process group leader (setsid()wants to make the calling process the process group leader of a newprocess group, so it fails in that case).

需要fork()并让子调用setsid()确保进程调用setsid()还不是进程组领导(setsid()想让调用进程成为进程组的进程组领导,因此在这种情况下失败)。

回答by zeekvfu

man 2 setsid, you will get the following description:

man 2 setsid,您将获得以下描述:

setsid() creates a new session if the calling process is not a process group leader. The calling process is the leader of the new session, the process group leader of the new process group, and has no controlling terminal. The process group ID and session ID of the calling process are set to the PID of the calling process. The calling process will be the only process in this new process group and in this new session.

如果调用进程不是进程组领导,setsid() 会创建一个新会话。调用进程是新会话的leader,新进程组的进程组leader,没有控制终端。调用进程的进程组 ID 和会话 ID 设置为调用进程的 PID。调用进程将是这个新进程组和这个新会话中的唯一进程。

If a process group leader is allowed to call setsid(), create a new session and a new process group(with the same process group id), it will lead to a process group id conflict.

如果允许进程组长调用setsid()、创建新会话和新进程组(具有相同的进程组id),则会导致进程组id冲突。