2012-04-15 8 views
8

Я пишу программу mapreduce, которая использует несколько каналов ввода-вывода (один канал для каждого процесса), чтобы получить окончательные результаты. У меня возникла проблема с созданием процессов. В частности, я получаю следующее сообщение об ошибке:fork() - множественные процессы и системные вызовы

wait error: Interrupted system call 

Это мой код, который порождает процессы:

while (values[inc]!=NULL) //provided array of text lines 
{ 
    if ((pid = fork()) == -1) { 
     perror("fork error"); 
     exit(EXIT_FAILURE); 
    }  

    else if (pid == 0) {    /* start of child process  */ 
     printf("Child process...\n"); 
     /* pipes[inc][1] is a file descriptor to which myMap writes some data 
      using the write() system call 
      mr is a struct that holds other function pointers */ 
     mr->myMap(pipes[inc][1],values[inc]); 
     exit(0); 
    } 
    else {       /* start of parent process  */ 
     printf("Parent process...\n"); 

     if ((wpid = wait(&status)) == -1) 
     /* Wait for child process.  */ 
      perror("wait error"); 
     else {      /* Check status.    */ 
      if (WIFSIGNALED(status) != 0) 
       printf("Child process ended because of signal %d\n", 
         WTERMSIG(status)); 
      else if (WIFEXITED(status) != 0) 
       printf("Child process ended normally; status = %d\n", 
         WEXITSTATUS(status)); 
      else 
       printf("Child process did not end normally\n"); 
     } 
     //close(fd[1]); 

     printf("Parent process ended\n"); 
    } 
    inc++; 
} 

После этого я создаю один поток

pthread_t newThread; 
pthread_create(&newThread,NULL,threadFunction,values); 
pthread_join(newThread,NULL); 

threadFunction использует выбор (), чтобы выяснить, какой файловый дескриптор готов к чтению и считывает его и помещает данные в словарь.

При запуске формы GDB отладчик, вывод программы:

Parent process... 
Child process... 
wait error: Interrupted system call 
Parent process ended 
Parent process... 
Child process ended normally; status = 0 
Parent process ended 
Parent process... 
Child process... 
Child process... 
wait error: Interrupted system call 
Parent process ended 

Я не знаю, как решить эту проблему. Какие-либо предложения?

Спасибо!

ответ

9

Вы должны поместить свой вызов wait() в цикл, и если он возвращает ошибку (-1) и errno == EINTR, продолжайте цикл. Любая другая ошибка является реальной ошибкой и должна рассматриваться как таковая.

вещи, как профилирующих таймеры могут вызвать сигналы, которые будут отправлены в процессе, однако сигнал, вероятно, вызывает прерывание является SIGCHLD, который, как вы знаете, вызывается, когда дочерний процесс изменяет состояние.

EDIT: Хорошо, я напишу ответ в коде:

do 
{ 
    wpid = wait(&status); 
} 
while (wpid == -1 && errno == EINTR); 
if (wpid == -1) 
{ 
    perror("wait error"); 
    return -1; 
} 
else 
{ 
    // we have wait status 
    ... 
} 
+0

Я не уверен, что вы имеете в виду. Пожалуйста, дополните. – Krzysiek

+1

@ Rafcio Я обновил свой ответ. – trojanfoe

+1

Спасибо. Это имеет смысл! :) – Krzysiek