2011-12-30 22 views
9

fork()とexecを使用して子プロセスを作成するサーバーコードに取り組んでいます。 fork()が成功し、CHILDシグナルが捕捉されたときにクリーンアップされると、子供のPIDが登録されます。KILL信号はすぐにプロセスを終了しますか?

サーバを停止する必要がある場合は、すべてのプログラムが強制終了され、最終的にはKILL信号が返されます。これは、登録されたすべてのPIDを反復処理し、CHILDシグナルハンドラがPIDを削除するのを待つことで機能します。子プログラムが正しく終了しなかった場合、これは失敗します。したがって、waitpidと組み合わせてkillを使用して、PIDリストがクリーンアップされ、ログが作成され、それ以外の場合は何か他の処理を実行するようにします。

は、次のサンプルコードを検討:waitpid(2)から

kill(pid, SIGKILL); 
waitpid(pid, NULL, WNOHANG); 

の抜粋:

のwaitpid():成功すると、状態変化した子プロセスのプロセスIDを返します。 WNOHANGが指定されていて、pidで指定された1つまたは複数の子(ren) がまだ状態を変更していない場合は、0が戻されます。エラーの場合、-1が返されます。

pidによって与えられるプロセスは、次の機能が起動する前にいつも消えていますか?上記の場合、waitpidはいつも-1を返しますか?

+2

KILL信号はむしろ残念です。また、 'kill'システムコールのリターンコードは何ですか? – fge

+0

"CHILDシグナルハンドラを待っています..." - SIGKILLのシグナルハンドラはありません。 SIGSTOPとSIGKILLを除くすべてのシグナルは 'sigaction'(ハンドラを呼び出すなど)によって設定されたもの、またはデフォルトを行います。 SIGSTOPはただ停止し、SIGKILLはプロセスを強制終了します。常に。処理や条件付きはありません。 (あなたが十分な権利を持っていないため、 'kill'システムコールが失敗することを除いて) – Damon

+0

@Damon: 'SIGKILL'は宛先プロセスで無視できません。しかし、それは質問/問題ではありません。ソースプロセス上の 'kill(2)'システムコールは、シグナルが(カーネルによって)デスティネーションプロセスのコンテキストで評価される前に戻ることができます。 'kill(2)'は基本的には非常にシンプルな非同期通信であり、すべての意味を持つように扱われなければなりません。 –

答えて

8

次の機能が起動する前に、pidによって与えられたプロセスは常に消えていますか?

保証はありません。マルチプロセッサでは、プロセスはCPU 0上にありますが、強制終了プロセスのカーネル内のクリーンアップはCPU 1上で行われます。これは古典的な競合状態です。シングルコアプロセッサでさえ、その保証はありません。

上記の場合、waitpidは常に-1を返しますか?

ほとんどの場合、おそらくそれは競合状態です。しかし、保証はありません。


あなたは状況に興味を持っていないので、このsemicodeはあなたのケースで、より適切な場合があります:

// kill all childs 
foreach(pid from pidlist) 
    kill(pid, SIGKILL); 

// gather results - remove zombies 
while(not_empty(pidlist)) 
    pid = waitpid(-1, NULL, WNOHANG); 
    if(pid > 0) 
     remove_list_item(pidlist, pid); 
    else if(pid == 0) 
     sleep(1); 
    else 
     break; 
+0

説明のおかげで、SIGCHILDハンドラがpidlistから項目を削除するので、私は提案されたコードを使用することができません。プロセスが実行されているかどうかを確認し、そうでない場合は削除し、それ以外の場合は削除します。 – Lekensteyn

+0

'WNOHANG'フラグを削除するだけで、あなたのコードは期待どおりに動作します。 –

+0

@Lekensteyn:既にリストを更新するSIGCHLDハンドラがある場合、このハンドラは 'waitpid'を呼び出してゾンビプロセスを削除します。そして、whileループは、a)すべてのプロセスが死んで埋まっているか、b)安全のためにいくつかのタイムアウトを待つだけでよい。 –

4

KILLシグナルハンドラが殺されたプロセスのCPU時間の間に実行されます。これは、waitpidコールよりもはるかに遅いため、特にロードされたシステムでは、waitpidは0を返すことができます。

関連する問題