2015-09-14 2 views
0

Я пытаюсь создать программу на C, в которой родитель создает массив доступных источников, а затем разворачивает некоторых детей, чтобы что-то сделать. На этом этапе дети создают массив, используя «доступный» массив родителя и еще один, используя только что созданный массив.Printf поведение при forking

Это мой код:

#include <time.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <unistd.h> 
#include <sys/types.h> 

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

    int i = 0; 
    int j = 0; 
    int status = 0; 
    int sources = 3; 
    int children = 3; 


    int *available = malloc(sources * sizeof(int)); 

    for (i = 0; i < sources; i++) 
     available[i] = 20; 

    for (i = 0; i < children; i++) 
    { 
     pid_t pid = fork(); 

     if (pid == 0) 
     { 
      // kid gets here 
      srand(getpid()); 

      printf("Kid %d created!\n", getpid()); 

      int *total = malloc(sources * sizeof(int)); 
      int *request = malloc(sources * sizeof(int)); 

      for (j = 0; j < sources; j++){ 
       total[j] = rand() % (available[j]/2); 
       printf("Kid(%d): Source(%d) = %d\n", getpid(), j, total[j]); 
      } 


      for (j = 0; j < sources; j++){ 
       request[j] = rand() % total[j]; 
       printf("REQUEST: Kid(%d): Source(%d) = %d\n", getpid(), j, request[j]); 
      } 

      printf("==============================================================\n"); 


      free(total); 
      free(request); 

      exit(0); 
     } 
     // parent gets here 

     sleep(1); // readable reasons 
    } 

    while ((wpid = wait(&status)) > 0); 

    free(available); 

    return 0; 
} 

Проблема

Проблема заключается в том, что иногда, когда я запускаю эту программу, я не получаю все отпечатки в моем терминале. Например, второй цикл должен печатать ровно 3 раза REQUEST: blabla, но иногда он печатается только дважды или вообще не печатается.

То, что я пытался

1) Согласно этому сообщению printf anomaly after "fork()" «когда выход из вашей программы идет к терминалу (экран), то линия буферизацией». Но все мои отпечатки имеют «\ n» в конце, поэтому у меня не должно быть проблем с буферизацией printf.

2) Пробовал 'fflush (stdout)' после каждой печати.

3) Пытался печатать на stderr, используя fprintf.

Итак, почему некоторые отпечатки не отображаются?

+1

Аномалии, с которыми вы связались, влияют на печать вещей ** перед ** вилкой, а не после. – Barmar

+0

Примечание: В программировании «дети» по-прежнему называют «детьми», чувак! – Olaf

+0

Любой полезный ответ? ^^ – matrix

ответ

3

Детский процесс завершается, когда total[j] является 0, потому что rand() % total[j] получает деление на нулевую ошибку.

Изменить

request[j] = rand() % total[j]; 

в

request[j] = total[j] ? rand() % total[j] : -1; 

Это будет показывать разделение в этом случае, и положить -1 в request указать ошибочный случай.

Это не имеет ничего общего с форкированием, за исключением того, что если бы у вас был цикл в родительском процессе, оболочка сообщила бы вам, что процесс рушился. Ваш родительский процесс не сообщает о статусе выхода, который возвращает wait(), поэтому вы не видите этого.

+0

Я добавил ко второму циклу «if (total [j] == 0) {request [j] = 0; printf (..); continue;) Спасибо, что нашли проблема! :) – matrix