Krzysiek
Krzysiek

Reputation: 1527

fork() - multiple processes and system calls

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!

Upvotes: 8

Views: 2820

Answers (1)

trojanfoe
trojanfoe

Reputation: 122391

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
    ...
}

Upvotes: 11

Related Questions