20150119:TP:C:Fork:EN
Sommaire
Introduction
The purpose of this session is to introduce fork(2) and wait(2) by a series of examples.
Simple fork
Make it work
- Here is a simple example of code, headers have been removed, use manual pages to find them:
// basic_fork.c: simple example of fork /* * MESSAGE is a simple wrapper around printf so that printf call display the * PID in front of the message * Must have at least 2 arguments, NULL can be used for the empty case */ # define MESSAGE(fmt_, args...) printf("(%u): " fmt_, getpid(), args); int main() { int fork_ret, x = 0; fork_ret = fork(); if (fork_ret == -1) err(1, "Fork failed"); if (fork_ret) { MESSAGE("Inside parent\n", NULL); MESSAGE("Initial x: %d\n", x); x = -42; } else { MESSAGE("Inside child\n", NULL); MESSAGE("Initial x: %d\n", x); x = 42; } MESSAGE("parent id: %u\n", getppid()); MESSAGE("new x:%d\n", x); return 0; }
Run the code several time and observe the output.
Write your own
The purpose of this exercise is to launch two different algoritms on the same data using fork(2).
Here is the base code:
# define MESSAGE(fmt_, args...) printf("(%u): " fmt_, getpid(), args); void random_fill(int tab[], size_t len) { for (int *cur = tab; cur != tab + len; ++cur) *cur = random() % 1024; } void swap(int *a, int *b) { int c = *a; *a = *b; *b = c; } void sort01(int tab[], size_t len) { for (size_t i = 0; i < len; ++i) { size_t min = i; for (size_t j = i + 1; j < len; ++j) if (tab[j] < tab[min]) min = j; swap(tab + i, tab + min); } } void sort02(int tab[], size_t len) { int move = 1; for (size_t i = 0; i < len && move; ++i) { move = 0; for (size_t j = 0; j < len - i - 1; ++j) { if (tab[j] > tab[j + 1]) { move = 1; swap(tab + j, tab + j + 1); } } } } int is_sorted(int tab[], size_t len) { size_t j; for (j = 1; j < len && tab[j - 1] <= tab[j]; ++j) {} return j == len; }
Your goal is to write a program that:
- fill an array of random integers (using the function random_fill().)
- fork:
- the parent runs the algoritm sort01 on the array
- the child runs the algoritm sort02 on the array
- both processes (child and parent) verify the sorted array with (is_sorted) and write a message using (MESSAGE.)
- Write the full program, compile it an run it.
- Bonus question: name the algoritms sort01 and sort02
Waiting and time measure
We now want to run the previous algoritms (sort01 and sort02) and do some time measures.
Running and waiting
Our first step is to write the program that will fork and run the two algorithms. The program will follow this schema:
- Fill an array of random integers
- Do a first fork:
- the child runs sort01
- the parent wait (using wait(2)) for the death of its child
- Do a second fork:
- the child runs sort02
- the parent wait (using wait(2)) for the death of its child
Wall Clock Time
You'll need clock_gettime(2) to do time measures: we get the time before the fork and after the wait, the difference will give you the time of execution of the child (and thus the execution time of the algorithms.) To ensure a correct time measure, you'll need the option CLOCK_MONOTONIC.
CPU and system time
In order to get more advanced time information, we need to get access to the rusage data structure corresponding to the child. For that, you need to replace wait(2) with wait3(2).
The program
You can now write the main program. This program will display the execution time of each algorithm.