2013-05-24 21 views
8

私は乱数nを生成し、次にn回ループするプログラムを持っています。終了順に印刷しますか?

各反復で、値sleeptimeをランダム化し、forkを呼び出します。子プロセスはsleeptime秒間スリープしてから、インデックス変数の値で終了します。

親プロセスは再びループし、各プロセスが終了するのを待ちます。各プロセスが終了すると、私はプロセスのpidとchildidをログアウトしようとしていますが、これが問題に陥っています。ピッドが順番に印刷され、子どもは0のままです。

私は間違っていますか?

int main(int argc, char* argv[]) 
{ 

    // Wire up the timer 
    long time = elapsedTime(0); 

    /* Generate a random number between MINFORKS and MAXFORKS 
    */ 
    unsigned int seed = generateSeed(0); 
    int n = rand_r(&seed) % MAXFORKS + MINFORKS-1; 

    /* Log next step 
    */ 
    time = elapsedTime(1); 
    printf("%li: Number of forks = %i\n", time, n); 

    /* Hang on to the PIDs so we can wait for them after forking 
    */ 
    pid_t *PIDs = (pid_t *)(malloc(sizeof(*PIDs)*n)); 


    /* Fork n times 
    */ 
    for (int i = 0; i < n ; i++) 
    { 
     /* Call fork() and retain the returned identifier 
     */ 
     pid_t processIdentifier = fork(); 

     /* Randomize the child sleep time 
     */ 
     seed = generateSeed(0); 
     int sleeptime = rand_r(&seed) % MAXPAUSE + MINPAUSE; 

     /* Check for errors 
     */ 
     if (processIdentifier == -1) { 
      printf("Error: %i", errno); 
     } 


     if (!processIdentifier) 
     { 
      /* We're in the child process, 
      * sleep and then exit with 
      * i as the error code. 
      */ 

      usleep(sleeptime); 
      _exit(i); 
     } 
     else 
     { 
      /* We're in the parent: 
      * Store the PID and 
      * print out the results. 
      */ 

      PIDs[i] = processIdentifier; 

      time = elapsedTime(1); 
      printf("%li: Child %i, pid = %i, forked, waits %i usec\n", time, i, processIdentifier, sleeptime); 

     } 
    } 

    /* Log next step 
    */ 
    time = elapsedTime(1); 
    printf("%li: Finished forking, going to wait.\n", time); 

    /* 
    * Loop through the processes and wait for them 
    * to terminate. Then print the childid, and the 
    * the pid. 
    */ 

    for (int i = 0; i < n; i++) 
    { 

     /* Get the PID we want to track 
     */ 
     pid_t pid = PIDs[i]; 

     /* Wait for the child process 
     * and grab it's status info 
     */ 
     int status = NULL; 


     waitpid(pid, &status, 0); 

     int childid = -1; 
     if(WIFEXITED(status)) 
     { 
      childid = WTERMSIG(status); 
     } 

     /* Log the results 
     */ 
     time = elapsedTime(1); 
     printf("%li: Child %i, pid = %i, terminated\n", time, childid, pid); 
    } 

    /* All done! 
    */ 
    time = elapsedTime(1); 
    printf("All done. It only took %li milliseconds!", time); 
} 

免責事項、これは宿題(link here, may disappear at any time)ですが、私はすでにほぼすべてのそれのをやりました。私はちょうどそれのこの1つの側面をつかむのに困っている。

答えて

4

あなたのコードは、あなたの連続したwaitpid()の呼び出しで、あなたが提供している順序でpidを待っています。最初のパラメータとして-1を最初にwaitpid()に渡した場合(またはwait()を呼び出すだけの場合)、通知を受けるように特に指示されたものではなく、カーネルが通知する最初の子が表示されます。戻り値を調べて、それがどの子であったか(またはエラーが発生したかどうか)を確認します。

は、WEXITSTATUSではなく、待機状態からWTERMSIGを抽出しているためです。

2
for (int i = 0; i < n; i++) 
{ 
    pid_t pid = PIDs[i]; 
    int status = NULL; 
    waitpid(pid, &status, 0); 

まず、最初のプロセスが終了するのを待ってから、そのプロセスの情報を出力します。
次に、2番目のプロセスが終了するのを待ってから、そのプロセスの情報を出力します。
それで、3番目のプロセスが終了するのを待ちます...

そして、なぜ彼らは順番に報告されているのでしょうか?

を-1にすると、this pageは、のいずれかの子スレッドの代わりに特定のスレッドを待つことを示します。

また、印刷する直前にint childid = -1;があります。理由は分かりません。

関連する問題