2011-02-02 11 views
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を使用するとゾンビプロセスがたくさんあります。これを是正する方法は?これは、子プロセスの終了ステータスを待つために親プロセスを使用していないためです。

答えて

7

は、カーネルが自動的例えば、あなたの子供を享受するために持っているSIG_IGNSIGCHLDハンドラを設定します。

signal(SIGCHLD, SIG_IGN); 
2

はい、親プロセスは子プロセスの戻り状態を待つ必要があります。親プロセスでSIGCHILDをキャッチし、キャプチャメソッドでwaitpidを呼び出して非同期的に行うことができます。あなたは子プロセスのためのwaitへの意思がない場合は

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; 
    } 
    } 
} 

FYI:続きをwaitpidの上。

waitpid()がこの親プロセスの子プロセスをクリーンアップするように、最初のパラメータは-1に設定されています。このプロセスは現在終了状態です。最初のパラメータは+ ve - この場合はwaitpid )は、特定の子プロセスのみをクリーンアップします。ほとんどの場合、最初のパラメータを-1に設定すると、waitpid()のマニュアルページも参照されます。 2番目のパラメータは、子プロセスの終了/終了ステータスコードを抽出するために使用されます。 - waitpid()システムコールAPIは、システムコールAPIが呼び出されたときにステータスフィールドを埋めます。 最後のフィールドはフラグフィールドです - 現在は使用されていません - ほとんどの場合、flagsフィールドは0に設定されます。つまり、システムコールAPIのデフォルトの動作です。実際にフラグを使用する必要がある場合は、waitpid()のマニュアルページを参照してください。

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

関連する問題