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

Articles

GEEK

User's box
Username:
Password:

Forgot password?
New account

Shoutbox
timsattemme
[b][url=http ://www.montb lancsoldes.n et/]p<strong ><a href="http:/ /www.montbla ncsoldes.net /">pens</a>< /strong> <br > <strong><a href="http:/ /www.montbla ncsoldes.net /">mont blanc pens</a></st rong> <br>
timsattemme
<strong><a href="http:/ /www.montbla ncsoldes.net /">montblanc pens</a></st rong> <br> <strong><a href="http:/ /www.montbla ncsoldes.net /">montblanc pen</a></str ong> <br> <strong><a href="http:/ /www.montbla ncsoldes.net /">mont blanc</a></s trong> <br> <br> <stron
timsattemme
[b][url=http ://www.rolex menwatchesfa ke.com/]role x<strong><a href="http:/ /www.rolexme nwatchesfake .com/">rolex Yacht-Master II</a></stro ng> <br> <strong><a href="http:/ /www.rolexme nwatchesfake .com/">repli ca watches</a>< /strong> <br >
timsattemme
[b][url=http ://www.rolex menwatchesfa ke.com/]watc hes[/url][/b ] [b][url=http ://www.rolex menwatchesfa ke.com/]swis s replica watches[/url ][/b] [b][url=http ://www.rolex menwatchesfa ke.com/]swis s rolex replicas for sale[/url][/ b] [b][url=http ://www.rolex menwa
timsattemme
[b][url=http ://www.tomso utlethot.com /]2014 New styl<strong> <a href="http:/ /www.tomsout lethot.com/" >2014 New style toms shoes</a></s trong> <br> <strong><a href="http:/ /www.tomsout lethot.com/" >TOMS Official Outlet Store</a></s trong> <br>

Donate
Donate and help us fund new challenges
Donate!
Due Date: Sep 30
September Goal: $40.00
Gross: $0.00
Net Balance: $0.00
Left to go: $40.00
Contributors


News Feeds
The Register
Google Apple
grapple brings
crypto cop block to
Android
Who"s that at the
door, storage box
flingers? It"s the
hard drive makers.
No, they are n
Stray positrons
caught on ISS hint
at DARK MATTER
source
Oi, London thief.
We KNOW what you"re
doing - our
PRECRIME system
warned us
Monitors monitor"s
monitoring finds
touch screens have
0.4% market share
Why Oracle CEO
Larry Ellison had
to go ... Except he
hasn"t
iPhone 6: Will it
blend? We don"t
know, but it sure
CAN"T FLY
Gigantic bazaar
Alibaba WILL turn
share price up to
11, er, $68 for
biggest IPO ever in<
Samsung unlocks
Knox at zero bucks
Apple iStuff saved
by Beer
Slashdot
The Myths and
Realities of
Synthetic
Bioweapons
Europeans Came From
Three Ancestry
Groupings
Study: Chimpanzees
Have Evolved To
Kill Each Other
Slashdot Asks:
What"s In Your Home
Datacenter?
Dealership
Commentator:
Tesla"s Going To
Win In Every State
Microsoft Lays Off
2,100, Axes Silicon
Valley Research
Apple"s "Warrant
Canary" Has Died
Mystery Signal
Could Be Dark
Matter Hint In ISS
Detector
Dremel Releases 3D
Printer
A Beginner"s Guide
To Programming With
Swift
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
Topic:C
Search OSI about C.More articles by BBYUGB.
 viewed 101183 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 :

example1.c

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

int main ()
{
  printf("Hello Worldn");
  fork();
  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
  PID TTY TIME CMD
 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.

example2.c

#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);
  else
    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')

example3.c

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

int main ()
{
  int pid, status;

  if(fork())
    {
      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);
    }else{
      printf("I'm the Son, and sleepingn");
      sleep(1);
      printf("I'm the Son, and exitingn");
      exit(0);
    }

  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.

example4.c

#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.

multifork.c

#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");
      exit(EXIT_FAILURE);
    }else{
      int i;
      char * command = av[1], * arg;
      for(i = 2; i < ac; i++)
        {
          arg = av[i];
          if(!fork())
            execl(command, "", arg, NULL);
        }
      for(i = 2; i < ac; i++)
        {
          int status;
          wait(&status);
        }
      exit(EXIT_SUCCESS);
    }
}


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
aaaa
ccccc
bbbbb
[BBYUGB@home articledir]$ ./multifork /bin/echo aaaa bbbbb ccccc
aaaa
bbbbb
ccccc
[BBYUGB@home articledir]$ ./multifork /bin/echo aaaa bbbbb ccccc
aaaa
bbbbb
ccccc
[BBYUGB@home articledir]$ ./multifork /bin/echo aaaa bbbbb ccccc
bbbbb
ccccc
aaaa
[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.

Comments:
zethyr
2004-12-26 20:35:34
Good article.. too bad I cant use any of this because my only stable box is win =/
johnlr
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.
keoki
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''.
keoki
2004-12-31 02:31:42
Well, I should have said /is/ POSIX compliant instead of ``claims POSIX compliance''.
aidan
2004-12-31 13:27:21
very nice tute, can't wait for the multi-threading tute!
jnansley
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.
BBYUGB
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 :-)
chista
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
Anonymous
2008-04-03 10:32:57
can u kindly explain this "wait(&status);" statement in the code.
Anonymous
2008-07-07 10:49:32
excellent and informative...

Thanks for the creators..expect more on DB programmings also
Anonymous
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
Anonymous
2009-04-02 11:12:05
kindly explain wait(&status) statement
Anonymous
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)...
Anonymous
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
Anonymous
2009-05-04 10:10:06
Very useful to know about multithreading functions.
Anonymous
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
ashisht4u@rediffmail.com
Anonymous
2009-10-04 10:53:51
its very nice explanation..... update with some more examples..
ScottishPig
2011-02-05 20:22:18
Wonderful explanation. The typos are a bit distracting, however.
Anonymous
2011-03-04 08:56:43
thank you very much
Anonymous
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..)
amisauv
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(
amisauv
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.
amisauv
/* 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
amisauv
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
amisauv
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
amisauv
INFECTED CODES WRITTEN IN C\C++ on Tue 9th Dec 10am
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
amisauv
A C programme which can print the file name it is kept in on Tue 9th Dec 9am
amisauv
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 () {
amisauv
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
amisauv
// 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