Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can the order of execution of fork() be determined?

Tags:

c

fork

scheduling

I'm working on an exercise on the textbook "Operating System Concepts 7th Edition", and I'm a bit confused about how does fork() work. From my understanding, fork() creates a child process which runs concurrently with its parent. But then, how do we know exactly which process runs first? I meant the order of execution.

Problem
Write a C program using fork() system call that generates the Fibonacci sequence in the child process. The number of sequence will be provided in the command line.

This is my solution:

#include <sys/types.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>

void display_fibonacci_sequence( int n ) {
    int i = 0;
    int a = 1;
    int b = 1;
    int value;
    printf( "%d, %d, ", a, b );
    for( ;i < n - 2; ++i ) {
        value = a + b;
        printf( "%d, ", value );
        a = b;
        b = value;
    }
    printf( "\n" );
}

int main( int argc, char** argv ) {
    int n;
    pid_t pid;
    pid = fork();
    if( argc != 2 ) {
        fprintf( stderr, "Invalid arguments" );
        exit( -1 );
    }
    n = atoi( argv[1] );

    if( pid < 0 ) {
        fprintf( stderr, "Fork failed" );
        exit( -1 );
    }
    else if( pid == 0 ) {
        display_fibonacci_sequence( n );
    }
    else { // parent process
        // what do we need to do here? 
    }
}

To be honest, I don't see any difference between using fork and not using fork. Besides, if I want the parent process to handle the input from user, and let the child process handle the display, how could I do that?

like image 324
Chan Avatar asked Jul 14 '11 16:07

Chan


People also ask

What happens on fork () system call execution?

System call fork() is used to create processes. It takes no arguments and returns a process ID. The purpose of fork() is to create a new process, which becomes the child process of the caller. After a new child process is created, both processes will execute the next instruction following the fork() system call.

Which process executes first after a fork () system call is made?

The goal is to run the child process first. In short, the logic behind it is that if the child is ran first, the overhead of copy on write (COW) is eliminated if the child is calling exec since the parent does not have any chance to write to the address space.

Does parent or child execute first in fork?

One process is created to start executing the program. When the fork( ) system call is executed, another process is created. The original process is called the parent process and the second process is called the child process.

How many times fork is executed?

Fork #1 creates an additional processes. You now have two processes. Fork #2 is executed by two processes, creating two processes, for a total of four. Fork #4 is executed by half of the processes created by fork #3 (so, four of them).


4 Answers

You are asking many questions, I'll try to answer them in a convenient order.

First question

To be honest, I don't see any difference between using fork and not using fork.

That's because the example is not a very good one. In your example the parent doesn't do anything so the fork is useless.

Second

else {
    // what do we need to do here? 
}

You need to wait(2) for the child to terminate. Make sure you read that page carefully.

Third

I want the parent process to handle the input from user, and let the child process handle the display

Read the input before the fork and "handle" the display inside if (pid == 0)

Fourth

But then, how do we know exactly which process runs first?

Very few programs should concern themselves with this. You can't know the order of execution, it's entirely dependent on the environment. TLPI says this:

After a fork(), it is indeterminate which process—the parent or the child—next has access to the CPU. On a multiprocessor system, they may both simultaneously get access to a CPU.

Applications that implicitly or explicitly rely on a particular sequence of execution in order to achieve correct results are open to failure due to race conditions

That said, an operating system can allow you to control this order. For instance, Linux has /proc/sys/kernel/sched_child_runs_first.

like image 192
cnicutar Avatar answered Oct 09 '22 02:10

cnicutar


We don't know which runs first, the parent or the child. This is why the parent generally has to wait for the child process to complete if there is some dependency on order of execution between them.

In your specific problem, there isn't any particular reason to use fork(). Your professor probably gave you this just for a trivial example.

If you want the parent to handle input and the child to calculate, all you have to do is move the call to fork() below the point at which you handle the command-line args. Using the same basic logic as above, have the child call display_fibonacci_sequence, and have the parent simply wait

like image 25
JSBձոգչ Avatar answered Oct 09 '22 03:10

JSBձոգչ


The process which is selected by your system scheduler is chosen to run, not unlike any other application running on your operating system. The process spawned is treated like any other process where the scheduler assigns a priority or spot in queue or whatever the implementation is.

like image 2
Grambot Avatar answered Oct 09 '22 01:10

Grambot


But then, how do we know exactly which process runs first? I meant the order of execution.

There is no guarantee to which one ran first. fork returns 0 if it is the child and the pid of the child if it is the parent. Theoretically they could run at exactly the same time on a multiprocessor system. If you actually wanted to determine which ran first you could have a shared lock between the two processes. The one that acquires the lock first could be said to have run first.

In terms of what to do in your else statement. You'll want to wait for the child process to exit using wait or waitpid.

To be honest, I don't see any difference between using fork and not using fork.

The difference is that you create a child process. Another process on the system doing computation. For this simple problem the end user experience is the same. But fork is very different when you are writing systems like servers that need to deal with things concurrently.

Besides, if I want the parent process to handle the input from user, and let the child process handle the display, how could I do that?

You appear to have that setup already. The parent process just needs to wait for the child process to finish. The child process will printf the results to the terminal. And the parent process currently gets user input from the command line.

like image 2
Evan Avatar answered Oct 09 '22 03:10

Evan