2

私はこのようなコードを持っています...

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[READ] と fd[WRITE] は、パイプ ファイル記述子です。

連続して実行すると、ps axを使用するとゾンビプロセスが大量に発生します。これを修正する方法は?これは、子プロセスの終了ステータスを待機するために親を使用していないためですか...

4

3 に答える 3

7

wait子プロセスを意図していない場合は、カーネルが子を自動的に取得するようにSIGCHLDハンドラーを設定します。SIG_IGN

signal(SIGCHLD, SIG_IGN);
于 2011-02-02T10:19:53.310 に答える
2

はい、親は子の復帰ステータスを待つ必要があります。SIGCHILD親プロセスをキャッチしてwaitpidからキャプチャメソッドを呼び出すことで、非同期で実行できます。

于 2011-02-02T10:13:25.170 に答える
0

はい、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 にすることもできます。この場合、waitpid() はクリーンアップのみを行います。特定の子プロセス。最も一般的な使用法は、最初のパラメーターを -1 に設定することです。また、waitpid() のマニュアル ページも参照してください。2 番目のパラメーターは、子プロセスの終了/終了ステータス コードを抽出するために使用されます。システム コール API が呼び出されると、waitpid() システム コール API がステータス フィールドに入力されます。最後のフィールドは flags フィールドです - 現在は使用されていません - ほとんどの場合、flags フィールドは 0 に設定されます - つまり、システム コール API のデフォルトの動作です !!! 本当にフラグを使用する必要がある場合は、waitpid() のマニュアル ページを参照してください。

注: 送信したコードでは、execlp() が失敗した場合に _exit(1) が呼び出されます。そのため、execlp() が失敗する条件を設定し、その条件 _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つの回答に感謝します。この答えがより明確になることを願っています。ありがとうございました。

于 2013-08-07T09:49:50.263 に答える