CSC 1600 Unix Processes q Processes Goals of This Lecture q Process vs. program q Context switching q Creating a new process q fork: process creates a new child process q wait: parent waits for child process to complete q exec: child starts running a new program q system: combines fork, wait, and exec all in one 1
Program vs. Process q Program = Static executable file on the disk q Process = Program in execution, with its own q Address space (illusion of a memory) q,, BSS, heap, stack q Processor state (illusion of a processor) q Program counter, registers q Open file descriptors (illusion of a disk) q Either running, blocked, or ready q Can run multiple instances of the same program q Each as its own process, with its own process ID Process in Memory Command line arguments Environment variables 2
Program vs. Process Program (on the disk) int global1 = 0; int global2 = 0; void DoSomething() int local2 = 5; Process (in memory) Command line arguments Environment variables local 1 local 2 5 local2 = local2 + 1;... int main() char local1[10]; DoSomething();... global 1 global 2.start main.call DoSomething CPU Registers What if More Processes in Memory? q Each process has its own, and P0 Free space P1 P2 Free space OS 3
Process States Create Ready 2. PREEMPT 4. CONTINUE 3. SCHEDULE Running Running Running Running Blocked 1. SUSPEND Terminate 1. Process blocks and waits for an event (e.g., I/O) 2. Force running process to release the CPU 3. Scheduler picks another ready process to run 4. Event occurs (eg., I/O ready) 7 Process Control Block () Information associated with each process" Command line arguments Environment variables local 1 local 2 5 global 1 global 2.start main.call DoSomething CPU Registers Process Control Block Process (in memory) 4
CPU Switch From Process to Process Unix Processes fork wait exec 5
How To Create New Processes? q Underlying mechanism q A process runs fork to create a child process q Parent and children execute concurrently q Child process is a duplicate of the parent process parent fork() child 11 Fork System Call q Current process split into 2 processes: parent, child q Returns -1 if unsuccessful fork() q Returns 0 in the child q Returns the child s identifier in the parent ret = 0 ret = xxx 6
#include <sys/types.h> #include <unistd.h> #include <stdio.h> int main() pid_t ret; pid_t myid; Try It Out /* fork another process */ if (ret < 0) /* error occurred */ printf("fork Failed"); return 1; myid = getpid(); printf( ret = [%d], myid = [%d]\n, ret, myid); return 0; Fork System Call q The child process inherits from parent q identical copy of memory q CPU registers q all files that have been opened by the parent q Execution proceeds concurrently with the instruction following the fork system call 7
How fork Works pid = 25 File Resources switch(ret) case -1: perror( fork ); case 0: // I am the child <code for child > default: // I am parent... <code for parent > wait(0); UNIX 15 How fork Works pid = 25 pid = 26 Resources File ret = 26 switch(ret) case -1: perror( fork ); case 0: // I am the child <code for child > default: // I am parent... <code for parent > wait(0); UNIX ret = 0 switch(ret) case -1: perror( fork ); case 0: // I am the child <code for child > default: // I am parent... <code for parent > wait(0); 16 8
How fork Works pid = 25 pid = 26 Resources File ret = 26 switch(ret) case -1: perror( fork ); case 0: // I am the child <code for child > default: // I am parent... <code for parent > wait(0); UNIX ret = 0 switch(ret) case -1: perror( fork ); case 0: // I am the child <code for child > default: // I am parent... <code for parent > wait(0); 17 How wait Works pid = 25 pid = 26 Resources File ret = 26 switch(ret) case -1: perror( fork ); case 0: // I am the child <code for child > default: // I am parent... <code for parent > wait(0); wait UNIX ret = 0 switch(ret) case -1: perror( fork ); case 0: // I am the child <code for child > default: // I am parent... <code for parent > wait(0); 18 9
How exit Works pid = 25 pid = 26 Resources File ret = 26 switch(ret) case -1: perror( fork ); case 0: // I am the child <code for child > default: // I am parent... <code for parent > wait(0); UNIX ret = 0 switch(ret) case -1: perror( fork ); case 0: // I am the child <code for child > default: // I am parent... <code for parent > wait(0); 19 How fork Works (6) pid = 25 Process Status File Resources ret = 26 switch(ret) case -1: perror( fork ); case 0: // I am the child <code for child > default: // I am parent... <code for parent > wait(0); < > UNIX 20 10
Telling which process is which q Fork is called once q But returns twice, once in each process q Telling which process is which q Parent: fork() returns the child s process ID q Child: fork() returns a 0 if (ret!= 0) /* in parent */ else /* in child */ q Key Points Fork Example 1 q Both parent and child can continue forking void fork2() printf("l0\n"); fork(); printf("l1\n"); fork(); printf("\n"); L1 L0 L1 11
q Key Points Fork Example 2 q Both parent and child can continue forking void fork3() printf("l0\n"); fork(); printf("l1\n"); fork(); printf("l2\n"); fork(); printf("\n"); L2 L1 L2 L2 L0 L1 L2 q Key Points Fork Example 3 q Both parent and child can continue forking void fork4() printf("l0\n"); if (fork()!= 0) printf("l1\n"); if (fork()!= 0) printf("l2\n"); fork(); printf("\n"); L0 L1 L2 12
q Key Points Fork Example 4 q Both parent and child can continue forking void fork5() printf("l0\n"); if (fork() == 0) printf("l1\n"); if (fork() == 0) printf("l2\n"); fork(); printf("\n"); L0 L2 L1 Waiting for the Child to Finish q Parent may want to wait for children to finish q Example: a shell waiting for operations to complete q Waiting for any some child to terminate: wait() q Blocks until some child terminates q Returns the process ID of the child process q Or returns -1 if no children exist (i.e., already exited) q Waiting for a specific child to terminate: waitpid() q Blocks till a child with particular process ID terminates #include <sys/types.h> #include <sys/wait.h> pid_t wait(int *status); pid_t waitpid(pid_t pid, int *status, int options); 13
Other Useful System Calls q exit terminates the execution of the calling process: q getpid returns the identifier of the calling process. Example call (pid is an integer): pid = getpid(); q getppid returns the identifier of the parent. Summary q A process runs fork to create a child process q Parent and children execute concurrently q Child process is a duplicate of the parent process 14
C Program Forking Separate Process #include <sys/types.h> #include <unistd.h> #include <stdio.h> int main() pid_t pid; /* fork another process */ pid = fork(); if (pid < 0) /* error occurred */ printf("fork Failed"); return 1; else if (pid == 0) /* child process */ execl("/bin/ls", "ls", NULL); else /* parent process */ /* parent will wait for the child */ wait (NULL); printf ("Child Complete"); return 0; Executing New Unix Programs: exec 15
Executing a New Program q Fork copies the state of the parent process q Child continues running the parent program q with a copy of the process memory and registers q Need a way to invoke a new program q In the context of the newly-created child process q Example program null-terminated list of arguments (to become argv[] ) execl( /bin/ls, ls, -l, NULL); fprintf(stderr, exec failed\n ); execl vs. execv execl( /bin/ls, ls, -l, NULL); q is equivalent to char * argv[] = /bin/ls, -l, NULL; execv(argv[0], argv); Note the NULL string at the end 16
Example: A Simple Shell q Shell is the parent process q E.g., bash q Parses command line q E.g., ls l q Invokes child process q Fork, execv q Waits for child q Wait execv bash fork wait ls How execv Works (1) pid = 25 pid = 26 Resources File char * argv[ ] = /bin/ls, 0; < > int ret = fork( ); if (ret == 0) execv(argv[0], argv); <parent code> wait(null); ret = 26 ret = 0 char * argv[ ] = /bin/ls, 0; < > int ret = fork( ); if (ret == 0) execv(argv[0], argv); <parent code> wait(null); /bin/ls UNIX kernel 17
How execv Works (2) pid = 25 pid = 26 File Resources char * argv[ ] = /bin/ls, 0; < > int ret = fork( ); if (ret == 0) execv(argv[0], argv); <parent code> wait(null); ret = 26 Exec destroys the process image of the calling process. A new process image is constructed from the executable file (ls). /bin/ls UNIX kernel How execv Works (3) pid = 25 pid = 26 File Resources char * argv[ ] = /bin/ls, 0; < > int ret = fork( ); if (ret == 0) execv(argv[0], argv); <parent code> wait(null); cpid = 26 <first line of ls> < > < > < > /bin/ls UNIX kernel 18
The PATH environment: execlp and execvp execvp - Extension of execv - Searches for the program name in the PATH environment execlp char * argv[] = ls, -l, NULL; execvp(argv[0], argv); Just the program name, not the entire path - Extension of execv - Searches for the program name in the PATH environment execlp( ls, ls, -l, NULL); The system Function Combines fork, wait, and exec all in one int system(const char *string); Must include include <stdlib.h> Works as if string is typed into the shell Usually returns -1 if there is an error Example use system( mkdir systest ); 39 19
Hands On Write a C program that does the following: - Takes a list of file names from the command line 40./a.out readme code.cpp game.input - For each file in the list: Parent prints out the filename, forks child, waits for child readme code.cpp game.input Child displays the contents of the file (use more) invoke system( more readme ) invoke system( more code.cpp ) invoke system( more game.input ) Hands On (contd.) - Parent prints out N files processed, done! where N is the number of filenames in the command line. 20