2013-05-24 2 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), но я уже сделал почти все. У меня просто возникают проблемы с этим аспектом.

ответ

4

Ваш код ожидает от ваших заказов в том порядке, в котором вы предоставляете их в своих последовательных звонках waitpid(). Если вы перейдете -1 в качестве первого параметра в waitpid() вместо этого (или если вы просто позвоните wait()), вы получите первый ребенок, о котором сообщается вам ядро, а не тот, о котором вы специально просили уведомить вас. Проверьте возвращаемое значение, чтобы узнать, какой он был (или произошла ошибка).

childid остается 0, потому что вы извлекаете WTERMSIG из состояния ожидания, а не WEXITSTATUS.

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

Итак, сначала он ждет завершения первого процесса и затем распечатает информацию из этого процесса.
Затем он ждет завершения второго процесса и затем распечатает информацию из этого процесса.
Затем он ждет окончания третьего процесса ...

И вам интересно, почему их сообщают в порядке?

проход -1 до waitpid вместо, который this page говорит заставит его ждать любой ребенок нить вместо определенного потока.

Кроме того, непосредственно перед печатью у вас есть int childid = -1;. Не знаю, почему.