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