web-dev-qa-db-ja.com

setsid()の前にfork()する理由

プロセスをデーモン化するためにfork()の前にsetsid()を使用する理由

基本的に、プロセスをその制御端末から切り離してプロセスグループリーダーにしたい場合は、setsid()を使用します。

前にフォークせずにこれを行うことはできません。

どうして?

37
cerisier

まず、setsid()は、プロセスをプロセスグループのリーダーにしますが、新しいセッションのリーダーにもなります。独自のプロセスグループを取得したいだけの場合は、setpgid(0,0)を使用します。

ここで、すでにプロセスグループリーダーまたはセッションリーダーである場合に、setsid()がEPERMを返す実際の理由を理解するには、プロセスグループとセッションIDが、それらを作成するプロセスのプロセスIDから初期化されることを理解する必要がありますセッションリーダーpid == sidおよびプロセスグループリーダーpid == pgidの場合)。また、プロセスグループはセッション間を移動できません。

つまり、あなたがプロセスグループリーダーであり、新しいセッションの作成が許可されている場合、sidとpgidはpidに設定され、古いプロセスグループ内の他のプロセスは奇妙な状態のままになります:プロセスグループリーダーが突然彼らは別のセッションにいるので、彼ら自身もそうかもしれません。そしてそれは許されないので、カーネルによるEPERMです。

ここでfork()を実行すると、セッションまたはプロセスグループのリーダーではなくなり、sidとpgidをpidに設定しても安全です。そのようなグループには他のプロセスがないためです。

だから、うん、考えてみれば、それはすべて理にかなっている。

52
user175104

fork()を呼び出して子にsetsid()を呼び出し、setsid()を呼び出すプロセスがまだプロセスグループリーダーではないことを確認する必要があります(setsid()は呼び出しプロセスをnewプロセスグループのプロセスグループリーダーにします。その場合は失敗します)。

18
caf

_man 2 setsid_、次の説明が表示されます:

呼び出しプロセスがプロセスグループリーダーでない場合、setsid()は新しいセッションを作成します。呼び出しプロセスは、新しいセッションのリーダーであり、新しいプロセスグループのプロセスグループリーダーであり、制御ターミナルはありません。呼び出しプロセスのプロセスグループIDとセッションIDは、呼び出しプロセスのPIDに設定されます。呼び出しプロセスは、この新しいプロセスグループとこの新しいセッションで唯一のプロセスになります。

プロセスグループリーダーがsetsid()の呼び出しを許可されている場合、新しいセッションと新しいプロセスグループ(同じプロセスグループIDを持つ)を作成すると、プロセスグループIDの競合が発生します。

2
zeekvfu