
ラズベリーファイでGPIOをしばらくオンにする必要があり、サブプロセスを作成し、GPIOをしばらくしてからオフにする関数を作成しました。問題は、子プロセスが自分で死ぬようにしようとすると、ゾンビのように残っているということです。この関数は何度も実行されるため、この状態で継続することはできません。誰にも解決策はありますか?ありがとう
void my_function(GPIOClass* gpio,useconds_t time) { pid_t pid=fork(); if(pid==0) { signal(SIGALRM,killchild) gpio->setval_gpio("1"); usleep(time*1000); gpio->setval_gpio("0"); alarm(3); while(1); } }
答え1
親プロセスから子プロセスをインポートする必要があります。望むよりwait(2)
。現在起こっているように見えるのは、子プロセスコードを実行する場合のみ処理し、親プロセスの結果は無視するということです。したがって、親プロセスは子プロセスの終了後にクリーンアップ操作を実行しないため、PIDリークが発生します。
最も簡単な解決策は、条件else
に以下を追加することです。if
else if (pid > 0) {
int status;
waitpid(pid, &status, 0);
}
編集する:上記の条件は、子プロセスが完了するまで親プロセスをブロックします。子プロセスが終了すると、シグナルSIGCHLD
は親プロセスに送信され、デフォルトでは無視されます。ただし、POSIX.1-2001によれば、シグナルハンドラを明示的に設定すると、SIGCHLD
システムSIG_IGN
は自動的に子プロセスをクリーンアップしますが、親プロセスは子プロセスの終了状態を知ることができないことに注意することが重要です。 。
初期化関数に次のコードを追加します。
signal(SIGCHLD, SIG_IGN);