fork() - 多个进程和系统调用

时间:2012-04-15 08:30:01

标签: c fork

我正在编写一个mapreduce程序,它使用多个I / O管道(每个进程一个管道)来获得最终结果。我在创建流程时遇到问题。具体来说,我收到以下错误:

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

我不知道如何解决这个问题。有什么建议吗?

谢谢!

1 个答案:

答案 0 :(得分:10)

您需要将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
    ...
}