27438 total geeks with 3535 solutions
Recent challengers:
 Welcome, you are an anonymous user! [register] [login] Get a yourname@osix.net email address 



User's box

Forgot password?
New account

It's Friday... That's good enough for me!
non stop lolz here but thats soon to end thanks to uni, surely the rest of the world is going good?
how things are going guys? Here... boring...
I must be going wrong on the password lengths then, as long as it was done on ECB
lol... the key is in hex (MD5: of the string "doit" without the "'s) and is in lower case. Maybe i should have submitted this as a challenge!

Donate and help us fund new challenges
Due Date: Mar 31
March Goal: $35.00
Gross: $0.00
Net Balance: $0.00
Left to go: $35.00

News Feeds
The Register
Surface Pro 3
update has so much
new stuff for
sysadmins, we can"t
fit it all in one
750,000 beautiful
women do the
bidding of one
Bongfire of
Inanity: Jakarta
rozzers enforce
mass chill-out
Turnbull"s Digital
Office to "leave
you quivering with
VMware tells
partners, punters,
to pay higher
prices (probably)
LOOK UP, Brits ? is
that one of
LASER-gun drones
above you? LIKELY
Microsoft performs
reverse full-hybrid
with an on-premises
Court recording biz
with clients
forums breached
Google botches
another cloud
patch, this time
messing up App
Optus must hire
checkbox champion
after epic router,
voicemail borking
Ordnance Survey
Releases Mapping
Robobug: Scientists
Clad Bacterium With
Graphene To Make a
Working Cytobot
Millennial Tech
Workers Losing
Ground In US
Win Or Lose,
Discrimination Suit
Is Having an Effect
On Silicon Valley
GAO Denied Access
To Webb Telescope
Workers By Northrop
PayPal To Pay $7.7
Million For
Australia Passes
Mandatory Data
Retention Law
Micron and Intel
Announce 3D NAND
Co-Development To
Push SSDs Past 10TB
Passphrases That
Even the NSA Can"t
"Bar Mitzvah
Attack" Plagues
SSL/TLS Encryption
Article viewer

Introduction to C/Unix Multiprocess Programming - Fork and Exec

Written by:BBYUGB
Published by:Nightscript
Published on:2004-12-26 18:50:35
Search OSI about C.More articles by BBYUGB.
 viewed 104863 times send this article printer friendly

Digg this!
    Rate this article :
We'll just go through some very simple example code, to see how to use fork() and execl().

1. fork()

2. Process ID

3. wait()

4. execl()

1. fork()

Basically, the fork() call, inside a process, creates an exact copy of that process somewhere else in the memory (meaning it'll copy variable values, etc...), and runs the copy from the point the call was made (for the assembly kids : it means that the relative value of the next instruction pointer is also copied)

Now, let's take look at this :


#include <stdio.h>
#include <unistd.h>

int main ()
  printf("Hello Worldn");
  printf("Goodbye Cruel Worldn");

[BBYUGB@home articledir]$ ./example1
Hello World
Goodbye cruel world
Goodbye cruel world
[BBYUGB@home articledir]$

When we launch example1, it first goes through the first printf(). Then, the fork() makes a copy of example1. Finally, each one of example1 and its copy goes through the second printf().

2. Process ID

Just a some stuff that we need to know about PIDs :
On a unix system, each time a new process is launched it is assigned a unique integer identifier. The easy way to see PIDs is to use ps :

[BBYUGB@home articledir]$ ps
 2567 pts0 00:00:00 bash
 2614 pts0 00:00:00 run-mozilla.sh
 2615 pts0 00:00:05 gaim
 2622 pts0 00:00:05 firefox-bin
 2730 pts0 00:00:00 emacs
 2752 pts0 00:00:00 ps
[BBYUGB@home articledir]$

The only stuff we really need to undestand right now is that CMD is the process name, and PID its... well, PID (And don't forget to use the 'man ps' command kids).

Now, here's something more about the fork() call : it returns an int.
And that's the part that most people are not at ease with :
The fork is executed only once, but it returns two different values.

- In the copied process, called the parent (the one that made the call),
it returns the PID of the copy.

- In the copy, the child, it returns 0.
So, the parent "knows" who his childs are, but a child doesn't "know" his parent.

Moreover, by testing the return value of fork(), you can learn wich one of the parent or the child is running.


#include <stdio.h>
#include <unistd.h>

int main ()
  int pid;
  printf("Hello Worldn");
  pid = fork();

  if(pid != 0)
    printf("I'm the Father and my son's PID is %dn",pid);
    printf("I'm the Sonn");

  printf("Goodbye Cruel Worldn");

Note : yes, you can directly go 'if( fork() )...' instead of 'pid = fork(); if(pid != 0)'

[BBYUGB@home articledir]$ ./example2
Hello World
I'm the Son
Goodbye Cruel World
I'm the Father and my son's PID is 3450
Goodbye Cruel World
[BBYUGB@home articledir]$

3. wait()

The wait() call is used to tell a process to wait for one of his childs to end, before going on with it's own task. wait() takes the adress of an int, in wich it puts the exit status of the child it waited for (to know what you can do with that status, look at 'man 2 wait')


#include <stdio.h>
#include <unistd.h>

int main ()
  int pid, status;

      printf("I'm the Father, and waitingn");
      pid = wait(&status);
      printf("I'm the Father :n - my son's PID is %dn - my son's exit status is %dn", pid, status);
      printf("I'm the Son, and sleepingn");
      printf("I'm the Son, and exitingn");

  printf("Goodbye Cruel Worldn");

[BBYUGB@home articledir]$ ./example3
I'm the Son, and sleeping
I'm the Father, and waiting
I'm the Son, and exiting
I'm the Father :
 - my son's PID is 4101
 - my son's exit status is 0
Goodbye Cruel World
[BBYUGB@home articledir]$

Note that this time, the "Goodbye..." line is printed only once coz the child process exited before reaching the printf().

4. execl()

execve() is a way to replace the process calling it by a shell command.
Here, we'll use execl(), a frontend to this command.


#include <stdio.h>
#include <unistd.h>

int main ()
  printf("Calling execl...nn");
  execl("/bin/cat", "cat", "./example4.c", NULL);
  printf("Useless call to printf");

[BBYUGB@home articledir]$ ./example4
Calling execl...

#include <stdio.h>
#include <unistd.h>

int main ()
  printf("Calling execl...nn");
  execl("/bin/cat", "cat", "./example4.c", NULL);
  printf("Useless call to printf");
[BBYUGB@home articledir]$

We just used execl() to replace example4 with the 'cat ./example4.c' command.
The first argument of execl() is the path to the binary or the script you want to execute, and then there is the list of arguments, starting with the 0th (name of the command). The last argument must be NULL.

Now, we get to the important part.


#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main (int ac, char * av[])
  if(ac < 3)
      printf("usage : multifork command arg1 arg2 ...n");
      int i;
      char * command = av[1], * arg;
      for(i = 2; i < ac; i++)
          arg = av[i];
            execl(command, "", arg, NULL);
      for(i = 2; i < ac; i++)
          int status;

This sample primitive program takes a path to a binary as 1st argument, and any number of arguments.
It then creates a number of processes equal to the number of these arguments, and launches the command once on each argument.

[BBYUGB@home articledir]$ ./multifork /bin/echo aaaa bbbbb ccccc
[BBYUGB@home articledir]$ ./multifork /bin/echo aaaa bbbbb ccccc
[BBYUGB@home articledir]$ ./multifork /bin/echo aaaa bbbbb ccccc
[BBYUGB@home articledir]$ ./multifork /bin/echo aaaa bbbbb ccccc
[BBYUGB@home articledir]$

Looking at that, we can see that the processes' execution order isn't the same each time the program is called, wich is the main advantage of using this kind of programming : the processes are executed in the same time, instead of linearly.

That's all for today.
As soon as I've got some time, we'll have a look at multi-threading, and maybe then we'll use all that to program a simple http-server.

By the way, did I tell you about the man pages ?

Did you like this article? There are hundreds more.

2004-12-26 20:35:34
Good article.. too bad I cant use any of this because my only stable box is win =/
2004-12-27 00:24:50
Usually a child process will user _exit() instead of exit()

The function _exit is like exit(), but does not call any functions reg-
istered with the ANSI C atexit function, nor any registered signal han-
dlers. Whether it flushes standard I/O buffers and removes temporary
files created with tmpfile(3) is implementation-dependent. On the
other hand, _exit does close open file descriptors, and this may cause
an unknown delay, waiting for pending output to finish. If the delay is
undesired, it may be useful to call functions like tcflush() before
calling _exit(). Whether any pending I/O is cancelled, and which pend-
ing I/O may be cancelled upon _exit(), is implementation-dependent.
2004-12-31 02:28:06
You need to learn how to use man pages and include the appropriate header files that correspond to a particular function that you may use. Most notably, ``wait''. Which accepts a pointer to int and you have no prototype in scope. So in return, under a c89/90 implementation, having no declaration in scope means that the function's declaration is implicitly declared with external linkage and returning the object type ``int'' and does not give any information as to the types of its arguments. Now the definition of ``wait'' is defined differently, and as such you go about invoking undefined behaviour because the types are not compatible. The undefined behaviour bit is just an abstracted concept used because you can't second guess how implementation XYZ passes around a ``pointer to int'' because it isn't guaranteed that XYZ does it in the same way as implementation ABC. Highly portable code is a side-effect of well written code. Additionally, you need to be consistent with the use of fork and wait, in that they both return a type of ``pid_t'' which the only thing POSIX/sus guarantees is that it is a signed integer type and that it may not be wider than a ``long''. So it may very well be a long and if it returns a value not representable by the type ``int'', then you have a bloody problem.

Chilliwilli, please, provide reasoning as to why you ``strongly advise'' against the use of fork.
fork, I might add, is a part of POSIX. So on a system that claims POSIX compliance, you will find ``fork''.
2004-12-31 02:31:42
Well, I should have said /is/ POSIX compliant instead of ``claims POSIX compliance''.
2004-12-31 13:27:21
very nice tute, can't wait for the multi-threading tute!
2005-01-01 18:33:23
There is a growing movement towards the threaded model and away from the fork() model, but they are two different things - I'd say that this is an entirely appropriate subject for a tutorial.

This might help: http://www.cs.nmsu.edu/~jcook/Tools/pthreads/pthreads.html

I felt that the _exit() comment was in very good taste as well.
2005-01-04 12:29:21
thanks johnlr & keoki, I just learned a few things right now.
For the wait part, I'd say it's cause I went a bit too fast over that, since it wasn't the real point of the article, but it's no excuse :-)
2005-01-21 09:15:39
You said "So, the parent "knows" who his childs are, but a child doesn't "know" his parent." There is a way fro the child to leard how is the parent. getppid() function gives you back the parent id
2008-04-03 10:32:57
can u kindly explain this "wait(&status);" statement in the code.
2008-07-07 10:49:32
excellent and informative...

Thanks for the creators..expect more on DB programmings also
2008-07-26 15:36:07
how to handle files in the child and parent processes which are in turn calling functions where we have to pass the file pointers. This is urgent req, kindly reply ASP, email: venkat.vasa@gmail.com
2009-04-02 11:12:05
kindly explain wait(&status) statement
2009-04-09 23:04:48
this forking technique isn't very clever, because fork() gives you the child-processes ID (which is >0 in the parent-process and ==0 in the child-process)
SO it is a better idea to store the childs pid and pass it to waitpid, since this way you can deliberately choose the child-process you want to wait for and don't just wait for anyone of them (if you have multiple)...
2009-04-22 14:38:48
Highly portable code is a side-effect of well written code. Additionally, you need to be consistent with the use of fork and wait, in that they both return a type of ``pid_t'' which the only thing POSIX/sus guarantees is that it is a signed integer type and that it may not be wider than a ``long''. online game
2009-05-04 10:10:06
Very useful to know about multithreading functions.
2009-06-04 22:24:16
Its kind of ok article, I need some more information regarding multithreding with socket.
Can anyone plz provide me tht my email is
2009-10-04 10:53:51
its very nice explanation..... update with some more examples..
2011-02-05 20:22:18
Wonderful explanation. The typos are a bit distracting, however.
2011-03-04 08:56:43
thank you very much
2011-05-15 18:15:26
dud you are juz awesome and realy I appreciate for work. keep it up pls. your examples are very very clear and understandable for some newbie like me
Anonymously add a comment: (or register here)
(registration is really fast and we send you no spam)
BB Code is enabled.
Captcha Number:

Blogs: (People who have posted blogs on this subject..)
Creating a Lexical Analyzer in C on Tue 9th Dec 11am
#include<stdio.h> #include<string.h> #include<conio.h> #include<ctype.h> /*************************************** ************************* Functions prototype. **************************************** *************************/ void Open_File(
Controling digital circuit through computer on Tue 9th Dec 10am
this code access the lpt port.here only 4 of the total 8 pins are used but can be modified for full 8 pins.it has a complete GUI with mouse & keyboard interactive control panel.works well in win98, but not in winxp. #include<stdio.h> #include<conio.
/* Computerised Electrical Equipment Control */ /* PC BASED DEVICE CONTROLLER * on Tue 9th Dec 10am
#include<stdio.h> #include<conio.h> #include<dos.h> void main() { void tone(void); int p=0x0378; char ex={"Created By Mrc"}; int j; char ex1={"For Further Details & Improvements"}; int k; char ex2={"Contact : E-mail : anbudan
Calendar Program on Tue 9th Dec 10am
This program prints Weekdays of specified date. It even prints calendar of a given year too. /*Ccalendar library*/ #include<stdio.h> #include<string.h> #include<conio.h> int getNumberOfDays(int month,int year) { switch(month) { case
Calculator: on Tue 9th Dec 10am
#include"graphics.h" #include"dos.h" #include"stdio.h" #include"math.h" union REGS i,o; char text={ "7","8","9","*","4","5","6","/","1","2", "3","+","0","00",".","-","M","M+", "M-","+/-","MR","MC","x^2","sr","OFF","A C","CE","="}; int s=0,k=0,pass
This is a simple code that changes system time and date. It is written using c/c++ but can be easily converted to java. #include "stdio.h" #include "process.h" #include "dos.h" int main(void) { struct date new_date; struct date old_date; s
A C programme which can print the file name it is kept in on Tue 9th Dec 9am
BOOTSECTOR EDITOR: on Tue 9th Dec 9am
Code : /*program to save the partion table of your hard disk for future use. it will save your partition table in a file partition.dat */ #include<stdio.h> #include<bios.h> #include<conio.h> #include<stdlib.h> #include<ctype.h> void main () {
BLINKING STAR : on Tue 9th Dec 9am
#include<conio.h> #include<graphics.h> #include<stdlib.h> #include<dos.h> void main() { int gdriver=DETECT,gmode; int i,x,y; initgraph(&gdriver,&gmode,"e: cgi"); while(!kbhit()) { x=random(640); y=random(480); setcolor
// To print semicolons using C programming without using semicolons any where i on Tue 9th Dec 9am
// To print semicolons using C programming without using semicolons any where in the C code in program. // #include<stdio.h> #include<conio.h> void main() { char a; a=59; if(printf("%c",a)){} getch();

Test Yourself: (why not try testing your skill on this subject? Clicking the link will start the test.)
BSD sockets API by skrye

This is a test of your knowledge of the BSD socket interface
C Programming by keoki

This test is aimed at a C programmer that is at an intermediate level.

Your Ad Here
Copyright Open Source Institute, 2006