170 likes | 288 Views
Operating Systems Lecture 9 Fork and Exec Read Ch 4.4 - 4.5. Process Creation. A parent process creates child process(es). Parent. Child. Child. The fork( ) command. In UNIX, a child process is created with the fork( ) command. cpid = fork( );
E N D
Operating SystemsLecture 9 Fork and Exec Read Ch 4.4 - 4.5
Process Creation • A parent process creates child process(es). Parent Child Child
The fork( ) command • In UNIX, a child process is created with the fork( ) command. cpid = fork( ); • This creates a copy of the process that executed the fork( ) command. • Address spaces for the two processes are (almost) identical. • Both processes have identical open files • Both processes have the program counter (PC) pointing to the statement after the fork( ) command. • The ID of the child process is returned to the parent by fork( ). • Zero is returned to the child process.
Using fork( ) • Example: • int main( void) { • int cpid; • cpid = fork( ); • cout << "Hello there." << endl; • } • Question: What is the output? Demo 1
Diagram of fork( ) We will draw this in class. Question: What is the difference between the two processes?
Distinguishing Parent and Child • Typical code to distinguish parent and child: • cpid = fork( ); • if (cpid == 0) { • //child code • } else { • //parent code • } Demo 2
Multiple forks • What is the output of the following code? • int main (void) { • int cpid, cpid2; • cpid = fork( ); • cpid2 = fork( ); • if (cpid == 0) { • cout << "I am the first child." << endl; • } else if (cpid2 == 0 ) { • cout << "I am the second child." << endl; • } else { • cout << "I am the parent." << endl; • } • return 0; • } Demo 3
Diagram of two process code We will diagram this in class.
Distinguishing the grandchild from the child Question: How do you distinguish the grandchild from the child? We will write this code in class.
Multiple forks from the parent only Question: How do you get the first child not to fork( )? We will write this code in class.
The exec( ) function • There are many versions of the exec( ) function: • execv( ), execl( ), execlp( ), execv( ), execvp( ), etc. • We will use execlp( ) and execvp( ) execlp( "cmd", arg0, arg1, arg2 ..., NULL); execvp( "cmd", argv);
Properties of the exec( ) call • The process that calls exec( ) is demolished. • exec( ) overlays (most of) the address space of the caller with the executable file, cmd. • exec( ) overlays the memory image of the process. • The parameters are passed appropriately. • Note: Open files are inherited. • If you want both child1 and child2 to read/write to the same file, the parent should open it.
Example with execlp( ) int main(void) { int cpid; cpid = fork( ); if (cpid == 0) { //child execlp( "ls", "ls", "-l", NULL); } else { cout << "I am the parent." << endl; } return 0; } Demo 4
Process synchronization • The parent can wait for a child to terminate using the wait( ) function. int cpid_done, status; cpid_done = wait(&status); • The caller sleeps until any child terminates. • cpid_done gets the pid of the child that terminated. • status gets the exit status of the terminated process. int cpid_done, status, options = 0; cpid_done = waitpid(cpid, &status, options); • caller sleeps until child with cpid terminates. • returns the pid of the terminating child • stores the status of the terminating child in status.
Process Termination • A process terminates with the exit (status) call • This terminates the process. • It closes all open files associated with the process. • Destroys the image of the memory image.
Typical code using fork, exec and wait int main( void ) int cpid, cpid_done, status; cpid = fork( ); if (cpid == 0) { //child // call exec function with desired cmd } else { cpid = wait(&status); //rest of parent code } return 0; } Demo 5
Basic Shell code Pseudo-code fpr basic shell (not real C++ code): while (not EOF) { parse_command_line; (get command, args, redirect, etc.) p = fork( ); if (p == 0) { //redirect I/O (takes a few steps to do) // exec (cmd, args) } else { if (command doesn't end with &) wait( ); } }