2009-05-22 12 views
1

私はfork()でいくつかのプロセスをforkするプログラムを書きました。私はエラーがある場合、すべての子プロセスと母プロセスを終了したい。 exit(EXIT_FAILURE)を使用すると、子プロセスのみが強制終了されます。プログラムのすべてのプロセスを強制終了するにはどうすればよいですか?

私はシステムを考えています(「[program_nameの] killallを」)が、より良い方法がなければならない...

はあなたのすべてをありがとう! Lennart

答えて

5

UNIXでは、SIGTERM、SIGABRT、またはSIGPIPEまたはsthを送信します。母親のプロセスに似ています。明示的にブロックまたは無視しない場合、この信号はすべてのクライアントに自動的に伝播されます。

getppid()を使用してPIDに信号を送信し、kill()を送信して信号を送信します。

getppid()は、呼び出し元プロセスの親プロセス番号 を返します。

kill()システムコールを使用すると、任意のプロセスグループまたはプロセスに信号を送信できます。

備考: 1. systemを使用するのは悪です。内部機能を使用して信号を送信する。 はさらに悪いことになります。一度に実行されるプログラムのいくつかのインスタンスを考えてみましょう。

+0

SIGTERMはkillallによって送信されるデフォルト信号です。他のシグナル(SIGABRTなど)によって、プロセスが終了するとコアファイルが作成されることがあります。 –

+0

ありがとう、私はコアダンプを忘れていました。私の合理的な点は、エラー処理のためにABRTが適切かもしれないということでした。 – ypnos

+0

@ypnos「内部機能を使用して信号を送信する」どうやって? –

2

は、明示的に親が何らかの理由ためを死ぬときに、プロセスのすべての子に信号を送信するように設計されてprctl()コールがありますLinuxの

How to make child process die after parent exits?を参照してください。

は、私がチェックする必要があると私は2番目の午前どこにそれを行うことはできませんが、私は本当にSIGPIPESIGTERMSIGABRTについてypnosの主張が正しいとすべての子に伝播されていることはよく分かりません。

kill(-ppid)(マイナス記号に注意してください)を使用する場合、子プロセスがまだ親プロセスのプロセスグループに属している限り、カーネルはすべての子にすべての信号を送ります。

+0

私の前提の簡単なテスト:ターミナルウィンドウを開き、シェルでいくつかのバックグラウンドプロセスを実行します。シェルをきれいに終了すると、つまりEOF(Ctrl + D)を送信すると、バックグラウンドプロセスはそのまま残ります。しかし、窓を閉めれば、彼らは殺されるでしょう。理由:ウィンドウを閉じると、シェルプロセスのSIGPIPEが仮想端末を失うので、SIGPIPEがトリガーされます。 – ypnos

+0

私はそれが有効なテストだとは思わない。 AFAIKは端末を強制終了し、カーネルはSIGPIPEをプロセスグループ全体に送信します。これは、明示的なSIGPIPEを親プロセスだけに送信するユーザと同じではありません。 – Alnitak

0

自殺アプローチを検討してください。プロセスの開始時(親と子の両方)に、正の秒数でalarm()を設定してください。その時間内に計算が完了し、「エラーはありません」の場合は、alarm(0)に電話してタイマーをキャンセルします。そうでない場合はSIGALRMは(あなたが明示的にキャッチするか、それを無視していないと仮定。)プロセスを強制終了します

まあ、代わりにこの反対ケースを作るだけでダウン投票:)

あなたのお母さんプロセスがによって開始されていない場合
+3

はdownvoteが、しませんでした: - あなたはinferiourソリューション を与えた - あなたのソリューションが悪いプログラミングとして見ることができる - あなたのソリューションは唯一のユースケース の非常に制限されたセットのために働くだろう - あなたのソリューションは、独自の でいくつかの問題があります多くの理由のためにスタイルを修正しました - これらの欠陥のないソリューションは既に投稿されていました これは、あなたの答えがこの質問に対して間違っているという前提に導く可能性があります。 – ypnos

+1

それは公正です、ありがとうございます。私はそれが解決策だとは言っていませんが、オプションの一つです。 –

1

コマンドラインでは、deamonのように プロセスグループのリーダーではないかもしれません。

マザープロセスがプロセスグループリーダーであることを確認するには、 プロセス初期化中にsetsid()を呼び出します。あなたの子プロセスにおけるその後

、あなたはすべてのプロセスを終了させたい場合は:

PGID =はgetpgid();
kill(pgid、15);

また、一時停止し、すべてのあなたの兄弟を伝えるようなトリック、行うことができます。

キル(PGID、20);

そして再開:

キル(PGID、18);

関連する問題