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

8
我正在编写一个使用多个I/O管道(每个进程一个管道)获取最终结果的mapreduce程序。我在创建进程时遇到了问题。具体地说,我遇到了以下错误:
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个回答

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

我不确定你的意思,请详细说明。 - Krzysiek

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接