次の質問があります: SIGCHLD にシグナルハンドラを使用し、特定の場所で代わりに waitpid(3) を使用できますか?
これが私のシナリオです: ソケットをリッスンするデーモン プロセスを開始します (この時点では、それが TCP ソケットか UNIX ソケットかは関係ありません)。クライアントが接続するたびに、デーモンは要求を処理するために子を fork し、親プロセスは着信接続を受け入れ続けます。リクエストを処理する子は、ある時点でサーバー上でコマンドを実行する必要があります。この例で、次のようなコピーを実行する必要があると仮定しましょう:
cp -a /src/folder /dst/folder
そのために、clild は execl(3) (または execve(3) など) を使用して copy コマンドを実行する新しいプロセスを fork します。
コードをより適切に制御するために、コピーを実行している子プロセスの終了ステータスを waitpid(3) でキャッチすることが理想的です。さらに、私のデーモン プロセスは要求を処理するために子プロセスをフォークしているため、ゾンビ プロセスが作成されないように、SIGCHLD のシグナル ハンドラが必要です。
私のコードでは、signal(3) を使用して SIGCHLD のシグナル ハンドラをセットアップし、2 回 fork してプログラムをデーモン化し、ソケットで受信接続をリッスンし、プロセスを fork して、着信する各リクエストと子プロセスのフォークを処理します。コピーを実行する孫プロセスで、waitpid(3) を介して終了ステータスを取得しようとします。
何が起こるかというと、孫プロセスが終了すると、waitpid(3) がアクションを実行し、孫プロセスが成功して終了したにもかかわらず、waitpid(3) が -1 を返す前に、ハンドラによって SIGCHLD が捕捉されます。
私の最初の考えは、追加することでした:
signal(SIGCHLD, SIG_DFL);
接続しているクライアントを処理するために子プロセスをフォークする直前に、成功しませんでした。SIG_IGN を使用しても機能しませんでした。
私のシナリオを機能させる方法についての提案はありますか?
事前にご協力いただきありがとうございます。
PS。コードが必要な場合は投稿しますが、サイズが大きいため、必要な場合にのみ投稿することにしました。
PS2。私の意図は、私のコードを FreeBSD で使用することですが、私のチェックは Linux で実行されます。
編集[解決済み]:
私が直面していた問題は解決されました。「予期しない」動作は、ある時点でバグがあった私の waitpid(3) 処理コードが原因でした。
したがって、上記の方法を実際に使用して、デーモンのようなプログラムで signal(3) と waitpid(3) を共存させることができます。
この方法が、そのようなことを達成したい人に役立つことを願っています!