2017-10-15 25 views
2
#include <stdio.h> 
#include <stdlib.h> 
#include <unistd.h> 

int main (int argc, char *argv[]) { 
    pid_t childpid = 0; 
    int i, n; 

    if (argc != 2){  
     fprintf(stderr, "Usage: %s processes\n", argv[0]); 
     return 1; 
    }  
    n = atoi(argv[1]); 
    for (i = 1; i < n; i++) 
     if (childpid = fork()) 
     break; 

    if (childpid>0){ // parent process 
     while (i>1) { 
     wait(NULL); 
     i--; 
     } 
    } 

    fprintf(stderr, "i:%d process ID:%ld parent ID:%ld child ID:%ld\n", 
      i, (long)getpid(), (long)getppid(), (long)childpid); 
    return 0; 
} 

すべての子プロセスがこのコードで終了した後に、プロセス情報(親)をどのように印刷できますか。子プロセスが終了した後、親プロセスを実行する方法は?

出力:

i:1 process ID:2313 parent ID:2307 child ID:2314 
i:3 process ID:2315 parent ID:2314 child ID:0 
i:1 process ID:2314 parent ID:1 child ID:2315 

私が最初に終了した子プロセスを必要とし、その後親プロセスは、そのプロセス情報を印刷する必要があります。

答えて

3

あなたのプログラムの問題は、この文である - このため

if (childpid = fork()) 

それにfork()戻り子プロセスのPIDと子プロセスがループの実行に進むにつれて、親プロセスは、最初の反復でループを抜けますfork()は0を返します。プロセスの親として( - 2315 PID) - - あなたの出力に使用すると、子プロセス(2314 PID)を取得している理由です

i:1 process ID:2313 parent ID:2307 child ID:2314 
i:3 process ID:2315 parent ID:2314 child ID:0 

正しい文である -

if ((childpid = fork()) == 0) 
+0

正しい。しかし、必ずしも間違っているとは限りません。それは、必要とされるプロセス構造に依存します。それが現れたとき、親は子を作成します。これは壮大な子を作成します。偉大な巨大な子を作成します...あなたの代わりに、親プロセスの兄弟の子プロセスが作成されます。どちらも正しいですか(どちらかが正しい) - それがあなたが望むものならば。 –

+0

@JonathanLeffler質問した質問のもう1つの側面を説明していただきありがとうございます。この質問には、「すべての**子プロセスがこのコードで終了した後にプロセス情報(親)を印刷する」という質問があるため、親プロセスと親子プロセスの子プロセスが考慮されています。しかし、私はあなたに完全に同意しています。どちらも正しいプロセス構造に依存しています。再度、感謝します。 –

+0

あなたの答えは、私がしなかったオプションや代替品をカバーするので便利です。 –

4

待機トラッキングループを作りますより有益でより徹底した特に、ループの最初のサイクルでは、親プロセスにはn == 1があるため、決して待機しません。待つべき子がなくなるまで繰り返し待つ方がいいでしょう。

#include <stdio.h> 
#include <stdlib.h> 
#include <sys/wait.h> 
#include <unistd.h> 

int main(int argc, char *argv[]) 
{ 
    pid_t childpid = 0; 
    int i, n; 

    if (argc != 2) 
    { 
     fprintf(stderr, "Usage: %s processes\n", argv[0]); 
     return 1; 
    } 
    n = atoi(argv[1]); 
    printf("Creating %d sub-processes\n", n); 
    fflush(stdout); 
    for (i = 1; i < n; i++) 
    { 
     if ((childpid = fork()) != 0) 
      break; 
    } 

    printf("%d: i = %d, childpid = %d\n", (int)getpid(), i, childpid); 

    if (childpid != 0) 
    { 
     int corpse; 
     int status; 
     while ((corpse = wait(&status)) > 0) 
      printf("%d: child %d exited with status 0x%.4X\n", (int)getpid(), corpse, status); 
    } 

    printf("i: %d process ID: %5ld parent ID: %5ld child ID: %5ld\n", 
      i, (long)getpid(), (long)getppid(), (long)childpid); 
    return 0; 
} 

出力例(fork73としてコンパイルされたプログラム):あなたは `場合は(childpid =フォーク())`ステートメントがループを終了するには、親を引き起こすことを言うとき、あなたはもちろんです

$ fork73 4 
Creating 4 sub-processes 
62621: i = 1, childpid = 62622 
62622: i = 2, childpid = 62623 
62623: i = 3, childpid = 62624 
62624: i = 4, childpid = 0 
i: 4 process ID: 62624 parent ID: 62623 child ID:  0 
62623: child 62624 exited with status 0x0000 
i: 3 process ID: 62623 parent ID: 62622 child ID: 62624 
62622: child 62623 exited with status 0x0000 
i: 2 process ID: 62622 parent ID: 62621 child ID: 62623 
62621: child 62622 exited with status 0x0000 
i: 1 process ID: 62621 parent ID: 877 child ID: 62622 
$ 
関連する問題