fork()-多个进程和系统调用 [英] fork() - multiple processes and system calls

查看:82
本文介绍了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

我不知道如何解决该问题.有什么建议吗?

谢谢!

解决方案

您需要将wait()调用放入循环,如果返回错误(-1),并且errno == EINTR继续循环.任何其他错误都是真正的错误,应这样对待.

诸如配置计时器之类的事情可能会导致将信号发送到进程,但是可能导致中断的信号是SIGCHLD,您知道,当子进程更改状态时,该信号称为. /p>

好的,我将用代码写答案:

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

I am writing a mapreduce program that uses multiple I/O pipes (one pipe per process) to get some final results. I am having a problem with creating the processes. Specifically, I am getting the following error:

wait error: Interrupted system call

This is my code that spawns processes:

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++;
}

After this I am creating one thread

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

The threadFunction uses select() function to find out which file descriptor is ready to be read and reads it and puts data in a dictionary.

When running form gdb debugger, the program output:

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

I don't know how to resolve the issue. Any suggestions?

Thanks!

解决方案

You need to put your wait() call into a loop and if it returns an error (-1) and errno == EINTR continue the loop. Any other error is a real error and should be treated as such.

Things like profiling timers can cause signals to be sent to the process, however the signal probably causing the interruption is SIGCHLD, which as you know is called when a child process changes state.

EDIT: OK, I'll write the answer in code:

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

这篇关于fork()-多个进程和系统调用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆