I was trying to understand the double fork and stumbled upon this question here. After a lot of research this is what I figured out. Hopefully it will help clarify things better for anyone who has the same question.
In Unix every process belongs to a group which in turn belongs to a session. Here is the hierarchy…
Session (SID) → Process Group (PGID) → Process (PID)
The first process in the process group becomes the process group leader and the first process in the session becomes the session leader. Every session can have one TTY associated with it. Only a session leader can take control of a TTY. For a process to be truly daemonized (ran in the background) we should ensure that the session leader is killed so that there is no possibility of the session ever taking control of the TTY.
I ran Sander Marechal's python example daemon program from this site on my Ubuntu. Here are the results with my comments.
1. `Parent` = PID: 28084, PGID: 28084, SID: 28046
2. `Fork#1` = PID: 28085, PGID: 28084, SID: 28046
3. `Decouple#1`= PID: 28085, PGID: 28085, SID: 28085
4. `Fork#2` = PID: 28086, PGID: 28085, SID: 28085
Note that the process is the session leader after Decouple#1
, because it's PID = SID
. It could still take control of a TTY.
Note that Fork#2
is no longer the session leader PID != SID
. This process can never take control of a TTY. Truly daemonized.
I personally find terminology fork-twice to be confusing. A better idiom might be fork-decouple-fork.
Additional links of interest:
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…