Raspberry Pi(最新のRaspberry Pi)では、私はネットワーク要求の要件に従ってアプリケーションを作成し、さまざまなネットワーク要求の要件に従ってそれを終了するアプリケーションを作成しました。生成メカニズムはフォーク/実行です。終了はkill(childPid、SIGQUIT)を介して行われます。想像できるように、これは単純なC ++コードであり、うまく機能します。
つまり、/etc/rc.localで起動しないとうまく機能します。そこで実行するコマンドは適切な CD だけで済みます。
./effectPlayer &
うまく起動し、リクエストもうまく受け取り、ビルドもうまくいきますが(aplayにまたがっているので、動作時期を知らせるのが簡単です)、リクエスト時にaplayサブプロセスを完全に終了できません。通常どおり kill() を呼び出し、kill() は 0 を返します。しかし、プレイは続きます。
/etc/rc.localで作成すると、フォークやキルで特別な動作が提供されるため、これは奇妙な事実だと思いますが、何を理解していません。私は何を見逃していますか?
編集:質問に対する回答を追加しました。ロギングがオンの状態で/etc/rc.localで実行されると、アプリケーションは以下を報告します。
23:10:06 10-11-2019 (effectPlayer) 7: P1 64 elvenHall #command to start playing
23:10:06 10-11-2019 (sound) launched 1083: /usr/bin/aplay -q -... #what it forks/execs
23:10:10 10-11-2019 (effectPlayer) 7: X1000 #command to stop playing
23:10:10 10-11-2019 (sound) sending 3 to 1083, result 0 0 #what kill() is asked to do
翻訳後は、特定の効果を再生し、それを処理するためのプレイを作成するように求められます。操作して(音声が聞こえ)、すべての再生を停止するように指示します。正しいシグナルを使用して正しいPIDでkill()を正常に呼び出し、kill()はerrno = 0で0を返します。 aplayを除いて、まだ実行中です。
コマンドラインで同じシーケンスを実行すると、aplayが実際に終了することを除いて、すべてが同じように機能します。
SIGQUITをSIGKILLに変更すると、期待どおりに機能します。 effectPlayerがどのように起動しても、aplayは終了します。
今はゲームの奇妙な点について説明します。私はSIGKILLを使うのが好きではありません。重要なクリーンアップをスキップできます。しかし、動作します...
答え1
フォークとexecがそれを無視するので、ブートスクリプトからSIGQUITを無視することを継承しました。親プログラムでSIGQUITをデフォルト状態にリセットしてみてください。
答え2
これはrc.localで実行されるため、発生する可能性はありません。
まず、親プロセスが実際にシグナルを送信しているか(ここでいくつかのデバッグラインが必要な場合があります)、子プロセスが終了していないことを確認してください(pgrep aplayを実行し、親プロセスを終了してからpgrep aplayを再度実行してください)。また、SELINUXやその他のMACの奇妙な現象が発生しないとします。
kill() に応答しないプロセスは、権限、処理、PID など、いくつかの要因が原因で発生する可能性があります。子プロセス「aplay」を生成する親プロセス「エフェクトプレーヤー」があり、effectPlayerが子プロセスに終了信号を送信するようです。
setuidと友達に奇妙なことをしないと仮定すると、親と子の両方が同じ所有者を持つことになるので大丈夫です。
終了信号をブロックできますが、aplayはそうしないと確信しています。だから可能です。 SIGQUITをSIGKILLに変更し、変更されていることを確認できます。
最後に、PIDがあります。 pidは正しいですか?繰り返しますが、終了したいPIDを指し、それをpsコマンドと一致させるいくつかのデバッグラインがそれをテストします。時には、シェルでexecを使用して誤ったプロセスを終了することがあります。