
状況が変です。
「B」、「C」、「D」などの他の実行可能ファイルの名前をパラメータとして使用するCで書かれたプログラム「A」があります。 「A」の主な作業は、「B」、「C」などを分岐して開始し、衝突が発生したかどうかを確認することです。この場合、競合が発生したプロセスを再起動します。
さらに、プロセス「A」は、RTC同期のために別個のスレッドを実行する。 「A」で始まります/bin/sh -c A B C D etc
。
私は組み込み環境にあり、Linux 4.4.57から派生したカスタムカーネルを使用しています。
これで問題が発生します。時々私のプロセス「A」がゾンビになります!
私の観察のいくつか:
- 「A」を開始した親プロセスが
/bin/sh -c
まだ存在します。 - サブプロセス「B」、「C」などは終了していない。
- 「A」は信号に応答する。
- 親プロセスを終了すると、
/bin/sh -c
「A」の親プロセスはinit(1)になりますが、プロセスはまだゾンビプロセスです。 - ゾンビ「A」を殺す唯一の方法は
kill -9 «pid-of-A»
; - RTC同期スレッドはまだ実行中です! ;
「A」がシグナルに応答し、内部スレッドが実行され続けているため、このゾンビプロセスが私を狂わせます。
この行動をどのように説明すべきでしょうか?カーネルビルドの設定に関連していますか?
編集する:コードを詳しく見てみると、「A」が次のコマンドを使用してデーモンで始まることがわかりました。
start-stop-daemon -b --start --quiet --pidfile /var/run/A.pid --background --exec /bin/sh -- -c "A B C D > /var/log/log 2>&1"
修正する: pthread_exit() を呼び出して同じ動作を複製することができました。問題は、ソースソースからphread_exitへの参照が見つからないことです。メインスレッドが他のすべてのスレッドのアクティブ状態を維持するのを停止する別の方法はありますか?
答え1
ゾンビプロセスは完了しましたが、まだプロセステーブルにエントリがあるプロセスです。たとえば、その子プロセスがまだ生きているからです(参照:ウィキペディア)。
だから、おっしゃるとおり、B、C、Dが死なず、Aが完成すれば、B、C、Dも完成するまでゾンビになります。
これは通常の動作です。
したがって、これはAのバグのように見えます。子供を監視する必要があるため、子供が生きている間は死んではいけません。 Aのバグを修正してゾンビに変わるかどうか心配しないでください。
答え2
pthread_exit()
関数で使用する場合main()
、この投稿基本スレッドはゾンビ状態に入ることができますが、他のスレッドは引き続き実行されることを示します。召喚は完全に合法的pthread_exit()
であるため、main()
これは正常であり、この特別なアンデッドは無害であると仮定します。これを無視したり、そこで使用する代わりに、main()
別のスレッドを待つことができますpthread_exit()
。
答え3
dmesgを見て問題と解決策を見つけました。 procファイルのカスタムカーネル関数によって発生した「内部エラー:申し訳ありません:817 [#1] ARM」があることがわかりました。ゾンビになったプロセスのメインスレッドがprocファイルを読み込みます。機能を修正しましたが、プロセスは終了しなくなりました。とにかく、皆さんありがとうございます。