<< Chapter < Page | Chapter >> Page > |
In this section, we explore how programs access multiprocessing features.
These examples are written in C using the POSIX 1003.1 application programming interface. This example runs on most UNIX systems and on other POSIX-compliant systems including OpenNT, Open- VMS, and many others. In this example, the program creates a new process using the
fork( )
function. The new process (child) prints some messages and then changes its identity using
exec( )
by loading a new program. The original process (parent) prints some messages and then waits for the child process to complete:
int globvar; /* A global variable */
main () {int pid,status,retval;
int stackvar; /* A stack variable */globvar = 1;
stackvar = 1;printf("Main - calling fork globvar=%d stackvar=%d\n",globvar,stackvar);
pid = fork();printf("Main - fork returned pid=%d\n",pid);
if ( pid == 0 ) {printf("Child - globvar=%d stackvar=%d\n",globvar,stackvar);
sleep(1);printf("Child - woke up globvar=%d stackvar=%d\n",globvar,stackvar);
globvar = 100;stackvar = 100;
printf("Child - modified globvar=%d stackvar=%d\n",globvar,stackvar);retval = execl("/bin/date", (char *) 0 );
printf("Child - WHY ARE WE HERE retval=%d\n",retval);} else {
printf("Parent - globvar=%d stackvar=%d\n",globvar,stackvar);globvar = 5;
stackvar = 5;printf("Parent - sleeping globvar=%d stackvar=%d\n",globvar,stackvar);
sleep(2);printf("Parent - woke up globvar=%d stackvar=%d\n",globvar,stackvar);
printf("Parent - waiting for pid=%d\n",pid);retval = wait(&status);
status = status>>8; /* Return code in bits 15-8 */
printf("Parent - status=%d retval=%d\n",status,retval);}
}
The key to understanding this code is to understand how the
fork( )
function operates. The simple summary is that the
fork( )
function is called once in a process and returns twice, once in the original process and once in a newly created process. The newly created process is an identical copy of the original process. All the variables (local and global) have been duplicated. Both processes have access to all of the open files of the original process.
[link] shows how the fork operation creates a new process.
The only difference between the processes is that the return value from the
fork( )
function call is 0 in the new (child) process and the process identifier (shown by the
ps
command) in the original (parent) process. This is the program output:
recs % cc -o fork fork.crecs % fork
Main - calling fork globvar=1 stackvar=1Main - fork returned pid=19336
Main - fork returned pid=0Parent - globvar=1 stackvar=1
Parent - sleeping globvar=5 stackvar=5Child - globvar=1 stackvar=1
Child - woke up globvar=1 stackvar=1Child - modified globvar=100 stackvar=100
Thu Nov 6 22:40:33Parent - woke up globvar=5 stackvar=5
Parent - waiting for pid=19336Parent - status=0 retval=19336
recs %
Tracing this through, first the program sets the global and stack variable to one and then calls
fork( )
. During the
fork( )
call, the operating system suspends the process, makes an exact duplicate of the process, and then restarts both processes. You can see two messages from the statement immediately after the fork. The first line is coming from the original process, and the second line is coming from the new process. If you were to execute a
ps
command at this moment in time, you would see two processes running called “fork.” One would have a process identifier of 19336.
Notification Switch
Would you like to follow the 'High performance computing' conversation and receive update notifications?