Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why aren't my processes running concurrently?

Tags:

c

fork

process

pid

My questions are:

1.) How can I get the parent process to always die last? I get that this isn't being accomplished because the parent is the first pid that gets ran, but I don't know how to change it.

2.) How do I get my child processes to execute at the same time like his? I've even bumped the number up really high to see if it was just a coincidence, but it appears to not be.

EDIT: SOLUTIONS

1.) added wait(NULL) twice in inner Default
2.) was happening. used sleep(1) to prove it.

My code is as follows

#include <stdio.h>
int main() {
    int pid, i;
    pid = fork();
    switch(pid) {
        case -1:
            // error
            printf("Fork error");
            break;
        case 0:
            // child process
            printf("First child is born, my pid is %d\n", getpid());
            for(i=1; i<10; i++)
                printf("First child executes iteration %d\n", i);
            printf("First child dies quietly.\n");
            break;
        default:
            // parent process
            printf("Parent process is born, my pid is %d\n", getpid());
            pid = fork();
            switch(pid) {
                case -1:
                    // error
                    printf("Fork error");
                    break;
                case 0:
                    // child process
                    printf("Second child is born, my pid is %d\n", getpid());
                    for(i=1; i<10; i++)
                        printf("Second child executes iteration %d\n", i);
                    printf("Second child dies quietly.\n");
                    break;
                default:
                    // parent process
                    printf("Parent process dies quietly.");
        }
    }
    return 0;
}

My output always looks like this:

Parent process is born, my pid is 7847  
First child is born, my pid is 7848  
First child executes iteration: 1  
First child executes iteration: 2  
First child executes iteration: 3  
First child executes iteration: 4  
First child executes iteration: 5  
First child executes iteration: 6  
First child executes iteration: 7  
First child executes iteration: 8  
First child executes iteration: 9  
First child executes iteration: 10  
First child dies quietly.  
Parent process dies quietly.  
Second child is born, my pid is 7849  
Second child executes iteration 1  
Second child executes iteration 2  
Second child executes iteration 3  
Second child executes iteration 4  
Second child executes iteration 5  
Second child executes iteration 6  
Second child executes iteration 7  
Second child executes iteration 8  
Second child executes iteration 9  
Second child executes iteration 10  
Second child dies quietly.  

My assignment is:

Write a C program ("procs.c") that creates three processes: a parent process that creates two child processes.

The first child should do the following:

  • display "First child is born, my pid is ..."

  • display ten times the message "First child executes iteration X", where X is the number of the iteration

  • display "First child dies quietly."

The second child should do the following:

  • display "Second child is born, my pid is ..."

  • display ten times the message "Second child executes iteration X", where X is the number of the iteration

  • display "Second child dies quietly."

The parent process should do the following:

  • display "Parent process is born, my pid is ..."

  • create the first child

  • create the second child

  • display "Parent process dies quietly."

Compile the program using gcc and name the executable "procs". Execute the program several times and notice how the output of the two children interlace.

A possible output of this program is:

nova> ./procs

Parent process is born, my pid is 7847  
First child is born, my pid is 7848  
First child executes iteration: 1  
First child executes iteration: 2  
First child executes iteration: 3  
First child executes iteration: 4  
First child executes iteration: 5  
Second child is born, my pid is 7849  
Second child executes iteration 1  
Second child executes iteration 2  
Second child executes iteration 3  
First child executes iteration: 6  
Second child executes iteration 4  
Second child executes iteration 5  
Second child executes iteration 6  
First child executes iteration: 7  
Second child executes iteration 7  
Second child executes iteration 8  
Second child executes iteration 9  
Second child executes iteration 10  
Second child dies quietly.  
First child executes iteration: 8  
First child executes iteration: 9  
First child executes iteration: 10  
First child dies quietly.  
Parent process dies quietly.  
like image 714
caleb.breckon Avatar asked Sep 07 '12 05:09

caleb.breckon


People also ask

Do parent and child processes run concurrently?

Father and child processes do run concurrently, and it is not predictable which process is running at what time. From a first inspection you have a loop that starts from the father process and creates 8 child processes, that on their hand each creates other child processes!

Can a process have multiple child processes?

fork() is a system call function which can generate child process from parent main process. Using some conditions we can generate as many child process as needed. We have given n , we have to create n-child processes from same parent process (main process ).

How do you create multiple processes of a child?

Creating multiple process using fork() Explanation – Here, we had used fork() function to create four processes one Parent and three child processes. An existing process can create a new one by calling the fork( ) function. The new process created by fork() is called the child process.


1 Answers

  1. The appropriate parent process should wait (using wait() or waitpid() or a platform-specific variant) for its children to die before exiting.

  2. Concurrent execution requires the scheduler to get a chance to run. You can force the issue with appropriate sleep (micro-sleep, nano-sleep) operations. Some system calls will help (so fflush(0) might help).


#include <stdio.h>
#include <sys/wait.h>
#include <time.h>
#include <unistd.h>

int main(void)
{
    int pid, i;
    struct timespec tw = { .tv_sec = 0, .tv_nsec = 10000000 };
    pid = fork();
    switch(pid)
    {
        case -1:
            printf("Fork error");
            break;
        case 0:
            printf("First child is born, my pid is %d\n", getpid());
            for(i=1; i<10; i++)
            {
                printf("First child executes iteration %d\n", i);
                nanosleep(&tw, 0);
            }
            printf("First child dies quietly.\n");
            break;
        default:
            printf("Parent process is born, my pid is %d\n", getpid());
            pid = fork();
            switch(pid)
            {
                case -1:
                    printf("Fork error");
                    break;
                case 0:
                    printf("Second child is born, my pid is %d\n", getpid());
                    for(i=1; i<10; i++)
                    {
                        printf("Second child executes iteration %d\n", i);
                        nanosleep(&tw, 0);
                    }
                    printf("Second child dies quietly.\n");
                    break;
                default:
                    printf("Parent process waiting for children.\n");
                    int corpse;
                    int status;
                    while ((corpse = waitpid(0, &status, 0)) > 0)
                        printf("Child %d died with exit status 0x%.4X\n", corpse, status);
                    printf("Parent process dies quietly.\n");
                    break;
            }
    }
    return 0;
}

Example output:

Parent process is born, my pid is 46624
First child is born, my pid is 46625
First child executes iteration 1
Parent process waiting for children.
Second child is born, my pid is 46626
Second child executes iteration 1
First child executes iteration 2
Second child executes iteration 2
First child executes iteration 3
Second child executes iteration 3
First child executes iteration 4
Second child executes iteration 4
Second child executes iteration 5
First child executes iteration 5
Second child executes iteration 6
First child executes iteration 6
Second child executes iteration 7
First child executes iteration 7
Second child executes iteration 8
First child executes iteration 8
Second child executes iteration 9
First child executes iteration 9
First child dies quietly.
Second child dies quietly.
Child 46625 died with exit status 0x0000
Child 46626 died with exit status 0x0000
Parent process dies quietly.

Note that the 10 millisecond delays almost force alternating execution. Without something similar, you are stuck with the idiosyncrasies of your system and its scheduler, and many a modern machine is just too fast!

like image 159
Jonathan Leffler Avatar answered Sep 29 '22 00:09

Jonathan Leffler