質問
私はこのようなコードを持っています...
c = fork();
if(c==0) {
close(fd[READ]);
if (dup2(fd[WRITE],STDOUT_FILENO) != -1)
execlp("ssh", "ssh", host, "ls" , NULL);
_exit(1);
}
close(fd[WRITE]);
FD [読み取り]およびFD [書き込み]はパイプファイル記述子です。
継続的に実行すると、PS AXを使用するとゾンビプロセスがたくさんあります。これを修正する方法は?これは、私が親を使って子プロセスの出口ステータスを待っていないからです...
解決
意図がない場合 wait
あなたの子供のプロセスについては、を設定します SIGCHLD
ハンドラーへ SIG_IGN
カーネルにあなたの子供を自動的に刈り取らせるために。
signal(SIGCHLD, SIG_IGN);
他のヒント
はい、親は子供の戻りステータスを待つ必要があります。キャッチすることで非同期に行うことができます SIGCHILD
親のプロセスで、そして電話してください waitpid
キャプチャメソッド。
はい、waitpid()は親から呼び出す必要があります。 waitpid()は、現在終了した状態にある親プロセスの子プロセスをクリーンアップします。
以下のコードをプログラムに追加できます。
if(c>0)
{
while(1){
ret = waitpid(-1,&status,0);
if(ret>0){
if(WIFEXITED(status)){
if(WEXITSTATUS(status) == 0){
printf("child process terminated normally and successfully\n");
}
else{
printf("child process terminated normally and unsuccessfully\n");
}
}
else{
printf("child process terminated abnormally and unsuccessfully\n");
}
}
if(ret<0) {
break;
}
}
}
参考:waitpidの詳細。
最初のパラメーターは-1に設定されているため、waitpid()がこの親プロセスの子プロセスをクリーンアップします。これは現在終了した状態です。最初のパラメーターは +veです。特定の子プロセス。最も一般的な使用は、最初のパラメーターを-1に設定することです。 2番目のパラメーターは、子プロセスの終了/終了ステータスコードを抽出するために使用されます-WaitPid()システムコールAPIは、システムコールAPIが呼び出されたときにステータスフィールドに入力します。最後のフィールドはフラグフィールドです - 現在未使用 - ほとんどの場合、フラグフィールドは0に設定されます - つまり、システムコールAPIのデフォルト動作!!!本当にフラグを使用する必要がある場合は、waitpid()のマニュアルページを参照してください。
注:送信したコードでは、_exit(1)はiff execlp()failsと呼ばれます。したがって、execlp()failの条件を置くことができ、その条件_exit()を呼び出すことができます。その理由は、execlp()関数がエラーが発生した場合にのみ返されるためです。
変更されたコードは以下のようにすることができます:
c = fork();
if(c==0) {
close(fd[READ]);
if (dup2(fd[WRITE],STDOUT_FILENO) != -1)
ret_execlp = execlp("ssh", "ssh", host, "ls" , NULL);
if(ret_execlp == -1 ) {
printf("execlp is failed");
_exit(1);
}
}
close(fd[WRITE]);
上記の2つの答えに感謝します。この答えがより明確になることを願っています。ありがとうございました。