*BSD News Article 1821


Return to BSD News archive

Xref: sserve comp.lang.c:29903 comp.sources.wanted:12726 comp.unix.misc:4272 comp.unix.questions:24113 comp.sys.apollo:12457 comp.unix.bsd:1856
Newsgroups: comp.lang.c,comp.sources.wanted,comp.unix.misc,comp.unix.questions,comp.sys.apollo,comp.unix.bsd,uiowa.comp.apollo
Path: sserve!manuel!munnari.oz.au!uunet!haven.umd.edu!wam.umd.edu!dododge
From: dododge@wam.umd.edu (David O. Dodge)
Subject: Re: Fork ?
Message-ID: <1992Jul6.043056.626@wam.umd.edu>
Sender: usenet@wam.umd.edu (USENET News system)
Nntp-Posting-Host: rac2.wam.umd.edu
Organization: University of Maryland, College Park
References: <1992Jul6.005853.21925@news.uiowa.edu>
Date: Mon, 6 Jul 1992 04:30:56 GMT
Lines: 111

In article <1992Jul6.005853.21925@news.uiowa.edu> gdcarson@icaen.uiowa.edu (Gregory Donald Carson) writes:
>Hello All;
>	I have a question about fork's.  I have a C program that I need to call
>repeatedly.  Meaning that I wish to be able to have this program called and
>run several times from the same program.  The C program that I need to call 
>takes a long time to run, and I want it to run, while the main program
>continues.  I have heard of a thing called a fork, and was hoping someone
>could explain it and perhaps send me an example. (I have been lead to believe
>that fork is the answer to this problem)

You probably need to do a fork-exec or fork-exec-wait combination.

fork() creates an identical copy of the currently running program. For
example if I run the program:

  #include <stdio.h>

  void main(void)
  {
    printf("This is the first line\n");
    fork();
    printf("This is the second line\n");
  }

the text "This it the first line" appears once on stdout but "This is
the second line" appears twice. fork() creates a duplicate process (with
a new process number) which is the child of the current process. All open file
descriptors and memory areas are duplicated as well.

The way you start a new program running concurrently with an existing program
is to use a fork-exec combination. fork() returns different values to the
parent and child processes. The parent gets back the pid of the child,
and the child gets back a 0. To start another program running concurrently
with your program, you fork() and then check the return value. If it's
nonzero then you just continue normally, but if it's a zero you exec() the
program you want to run.

For example, to run "/bin/ls" concurrently with a program:

  #include <stdio.h>

  void main(void)
  {
    printf("first line\n");

    if(!(fork()))
    {
      /* Child code here */

      execl("/bin/ls","ls",(char*)0);
    }

    /* parent contines here */

    printf("second line\n");
  }

The execl() routine above invokes the program "/bin/ls" with no arguments.
There are several variants of exec, so check the manual page to see which
one you need. The reason you need to do a fork before you exec is because
the way exec works is that it *replaces* the current process with the
specified program. A successful call to execl() never returns (it's sort
of like calling exit()). In this case the printf of "second line" only
occurs once, and it will be interspersed with the output from /bin/ls.

So what the above bit of code is doing is creating a subprocess and then
turning that into the /bin/ls program. The original program keeps
running. It does not wait for /bin/ls to finish.

If you need to wait for the subprocess to complete, you would do
something like:

  #include <stdio.h>
  #include <sys/types.h>
  #include <sys/wait.h>

  void main(void)
  {
    printf("first line\n");

    if(!(fork()))
      execl("/bin/ls","ls",(char*)0);
    else
      wait((union wait*)0);

    printf("second line\n");
  }

In this case the main program prints "first line", then /bin/ls is invoked,
and after /bin/ls has completed the main program continues and prints
"second line".

Note that these sample programs all worked on the Ultrix system I'm
using to post this, but there may be some minor differences on other 
flavors of Unix. Be sure to check the manual pages for fork(2),
execl(2), and wait(2) before you try anything fancy. Also if you're new
to fork() be sure to try some simple test programs to get an idea as to
how it behaves. You need to get a good feel for how wait() is handled if
you're going to be spawning multiple child processes, and if you're
going to be doing concurrent output (e.g. the first two sample programs
above) you should be sure you understand how file I/O behaves after a
fork().

>	The system I am using is under unix, and the C compiler is at least
>ansi compatible, beyond that I am not sure and really for portaability should
>avoid anything outside the ansi standard.

Any version of Unix out there should support fork(). It's the primary (if
not the only) way to create a new process.

                                             -Dave Dodge/dododge@wam.umd.edu