A simple fork example timed with chrono

I always wanted to experiment with parallel computing and multi threading. However, when and how to use parallel computing has always been a bit difficult to conceptualize for me. Until I discovered forking. Here I will describe a simple implementation of fork using the chrono Time c++ library to time the forked processes.

Forking consists in splitting a program into two parts so that each part can be executed simultaneously. Fork seemed the easiest of the c++ facilities to use for parallel computing because 1) call fork is simple; 2) fork is simpler to use than other thread management tools as thread; 3) it does not require the linking of extra libraries; 4) it fitted easily what I wanted to do: run the same functions simultaneously on different data. This is ideal for some of the lab situations we have in which many persons are administered the same task. Since 1) the type of data produced is the same for all of them and 2) the analysis we perform is the same for all of them, we would gain considerable time if could process them in parallel.

The code below represents a very simple implementation that I wrote assembling together various pieces I found on the web. I do not think the code below is particularly beautiful, elegant, clever or praiseworthy. I only know I would have been happy to find code as the one below when I was first starting to use fork. In fact, I found the code out there a bit too minimalistic or too complex. My goal is plainly to show code that is readable to someone that speaks c++ and wanted to try how fork works. Moreover, the example below should be easily adaptable to one own needs.

The code consists of three function calls. Main contains the fork command splitting the child and parent processes, which are `regulated’ through a switch command and wait(s) for both processes to end. Fibonacci is a recursive function computing fibonacci numbers from the cppreference website. I chose this function because I wanted a function the required computing times (e.g. it does not execute in 1 nano second) and because I think recursion is elegant. PrintOut is self explicable I hope.

 

#include <iostream>
#include <string>
#include <unistd.h>
#include <sys/wait.h>
#include <cstdlib>// Declaration for exit()
#include <chrono> // available from c++11
#include <ctime>


using namespace std;

long fibonacci(unsigned n)
{
if (n < 2) return n;
return fibonacci(n-1) + fibonacci(n-2);
}

int printOutput(string nameProcess, size_t nFibonacci)
{
cout << nameProcess << " started at ";
chrono::time_point<chrono::system_clock> start;
start = chrono::system_clock::now();
time_t startTime = chrono::system_clock::to_time_t(start);
cout << ctime(&startTime);

cout << nameProcess << "f(" << nFibonacci << ") = ";
cout << fibonacci(nFibonacci) << '\n';

cout << nameProcess << "finished computation at ";
chrono::time_point<chrono::system_clock> end;
end = chrono::system_clock::now();
time_t end_time = chrono::system_clock::to_time_t(end);
cout << ctime(&end_time);

cout << nameProcess << "elapsed time: ";
chrono::duration<double> elapsed_seconds = end-start;
cout << elapsed_seconds.count() << "s\n";

return 0;
}

int main()
{
pid_t pid;
pid = fork();
switch(pid)
{
case 0:
{
printOutput("CHILD ", 42);
exit(0);
}
case -1:
{
cout << "Failed to fork\n";
exit(1);
}
default:
printOutput("PARENT ", 42);
}
cout << "waiting for all processes to finish\n";
waitpid(-1, NULL, 0);
cout << "END\n";
return 0;
}

 

A more readable version of this code (e.g. with indentation respected) can be found on my github account.

It can be compiled as:

g++ -Wall –std=c++11 nameFile.cc -o test

Chrono is available from c++11, so the code needs to be compiled with the –std=c++11 flag.

On my (dated) machine it produced:

PARENT started at Fri Mar 18 20:55:39 2016
CHILD started at Fri Mar 18 20:55:39 2016

PARENT f(42) = 267914296
PARENT finished computation at Fri Mar 18 20:55:46 2016
PARENT elapsed time: 6.18824s
waiting for all processes to finish
CHILD f(42) = 267914296
CHILD finished computation at Fri Mar 18 20:55:46 2016
CHILD elapsed time: 6.43001s
END

 

Advertisements
A simple fork example timed with chrono

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s