2012-04-15 98 views
8

我正在编写一个mapreduce程序,它使用多个I/O管道(每个进程一个管道)来获得最终结果。我在创建流程时遇到问题。具体来说,我收到以下错误: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使用select( )函数来查找哪个文件描述符已准备好被读取并读取它并将数据放入字典中。

当运行形式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,因为你知道,当一个子进程改变状态被称为其。

编辑:好的,我会写的答案代码:

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

我不知道你的意思。请详细说明。 – Krzysiek 2012-04-15 08:48:44

+1

@Rafcio我已经更新了我的答案。 – trojanfoe 2012-04-15 08:53:40

+1

谢谢。这说得通! :) – Krzysiek 2012-04-15 09:01:50