130 likes | 466 Views
제 29 강 : fork(). fork(). FORK(2) Linux Programmer's Manual FORK(2) NAME fork - create a child process SYNOPSIS #include <unistd.h> pid_t fork(void); Called once, returned twice DESCRIPTION
E N D
제29강 : fork() fork()
FORK(2) Linux Programmer's Manual FORK(2) NAME fork - create a child process SYNOPSIS #include <unistd.h> pid_t fork(void); Called once, returned twice DESCRIPTION fork creates a child process that differs from the parent process only in its PID and PPID, and in the fact that resource utilizations are set to 0. File locks and pending signals are not inherited. Under Linux, fork is implemented using copy-on-write pages, so the only penalty incurred by fork is the time and memory required to duplicate the parent's page tables, and to create a unique task structure for the child. RETURN VALUE On success, the PID of the childprocess is returnedin the parent's thread of execution, and a 0 is returnedin the child's thread of execution. On failure, a -1 will be returned in the parent's context, no child process will be created, and errno will be set appropriately.
newproc 3334 fork trap kernel stack parent invokes fork() –3322 12-4 • 3327 Any empty slot in proc[]? • p1: parent • p2: child • Call newproc() • Parentreturns (1918) from newproc() with value 0 . • if(0) test fails. • go to 3344 -- assign child’s PID (p2) • End of fork() -- Parent’s system call is complete. • Parent may invoke wait() system call calls swtch() • Question: What if parent omit wait() system call? proc[PNEW] newproc() Image(PNEW) Image(PPARENT) PNEW -- Ready to run
newproc 3334 fork trap kernel stack child starts from swtch/fork3322 12-4 • Child is wakes up later in swtch() • Returns to the same place as parent -> 3334 newproc() • Remember …. parent started sh a.out from sh’s main() • but child starts from kernel 3334! • Passes the “if (newproc()) test” (value 1 was returned) into { } • Initialize struct user (whose u is this? new ppda) • 3335 Assigns parent’s PID (p1) into u (Linux returns 0 here) • Return from fork() system call. (see next page) • Usually, exec() follows fork(). (i.e. if (child) exec(“/bin/ls”) ) • exec() never returns. It is goto. Child code invokes exit(). savu(u) caller retires swtch() retu(proc[0]) CPU scheduler at work retu(proc[rp]) dispatch 2228 return(1) 2247
Overhead of fork() • 1915 -1916 (newproc()) while (n--) copyseg(a1++, a2++); copy struct u ----- reduce by thread lazy copy --------- share pages without copying as long as they are not written COW (Copy on Write) minimize fork() overhead
Example: exec() Try man exec main() {int pid; pid =fork(); if (pid = = 0) /* this is child */ {printf(“\n Hello, I am child! Now I’ll run date \n”); execlp(“/bin/date” ……); } else /* this is parent */ if (pid > 0) printf(“\n Hello, I am parent!\n”); wait();then parent’s remaining code } Only the child enters here (parent’s image was copied in fork) Overlay new a.out (exec()) Return to user mode To /bin/date’s main()
main(argv, … envp) { loop: print prompt (%) read a line from tty , take 1st word (eg ls ) search directories in $PATH hit? (yes. --- /bin/ls – start ls as child.) if (pid =fork()) /* child */ { execlp(“/bin/ls”, “/bin/ls”, (char *) 0); } else /* parent */ if (last char is not &) wait(); /*parent waits here if child is foregrgound */ goto loop: } How does shell work l s