Carnegie MellonIntroduction to Computer Systems15-213/18-243, spring 200915thLecture, Mar. 5thInstructors:Gregory Kesden and Markus PüschelCarnegie MellonECF Exists at All Levels of a System Exceptions Hardware and operating system kernel software Signals Kernel software Non-local jumps Application codePrevious LectureThis LectureCarnegie MellonToday Multitasking, shells Signals Long jumps More on signalsCarnegie MellonThe World of Multitasking System runs many processes concurrently Process: executing program State includes memory image + register values + program counter Regularly switches from one process to another Suspend process when it needs I/O resource or timer event occurs Resume process when I/O available or given scheduling priority Appears to user(s) as if all processes executing simultaneously Even though most systems can only execute one process at a time Except possibly with lower performance than if running aloneCarnegie MellonProgrammer’s Model of Multitasking Basic functions fork() spawns new process Called once, returns twice exit() terminates own process Called once, never returns Puts it into “zombie” status wait() and waitpid() wait for and reap terminated children execl() and execve() run new program in existing process Called once, (normally) never returns Programming challenge Understanding the nonstandard semantics of the functions Avoiding improper use of system resources E.g. “Fork bombs” can disable a systemCarnegie MellonShell Programs A shell is an application program that runs programs on behalf of the user. sh Original Unix shell (Stephen Bourne, AT&T Bell Labs, 1977) csh BSD Unix C shell (tcsh: csh enhanced at CMU and elsewhere) bash “Bourne-Again” Shellint main() {char cmdline[MAXLINE]; while (1) {/* read */printf("> "); Fgets(cmdline, MAXLINE, stdin); if (feof(stdin))exit(0);/* evaluate */eval(cmdline);} }Execution is a sequence of read/evaluate stepsCarnegie MellonSimple Shell eval Functionvoid eval(char *cmdline) {char *argv[MAXARGS]; /* argv for execve() */int bg; /* should the job run in bg or fg? */pid_t pid; /* process id */bg = parseline(cmdline, argv); if (!builtin_command(argv)) { if ((pid = Fork()) == 0) { /* child runs user job */if (execve(argv[0], argv, environ) < 0) {printf("%s: Command not found.\n", argv[0]);exit(0);}}if (!bg) { /* parent waits for fg job to terminate */int status;if (waitpid(pid, &status, 0) < 0)unix_error("waitfg: waitpid error");}else /* otherwise, don’t wait for bg job */printf("%d %s", pid, cmdline);}}Carnegie MellonWhat Is a “Background Job”? Users generally run one command at a time Type command, read output, type another command Some programs run “for a long time” Example: “delete this file in two hours”% sleep 7200; rm /tmp/junk # shell stuck for 2 hours A “background” job is a process we don't want to wait for% (sleep 7200 ; rm /tmp/junk) &[1] 907% # ready for next commandCarnegie MellonProblem with Simple Shell Example Shell correctly waits for and reaps foreground jobs But what about background jobs? Will become zombies when they terminate Will never be reaped because shell (typically) will not terminate Will create a memory leak that could theoretically run the kernel out of memory Modern Unix: once you exceed your process quota, your shell can't run any new commands for you: fork() returns -1% limit maxproc # csh syntaxmaxproc 3574$ ulimit -u # bash syntax3574Carnegie MellonECF to the Rescue! Problem The shell doesn't know when a background job will finish By nature, it could happen at any time The shell's regular control flow can't reap exited background processes in a timely fashion Regular control flow is “wait until running job completes, then reap it” Solution: Exceptional control flow The kernel will interrupt regular processing to alert us when a background process completes In Unix, the alert mechanism is called a signalCarnegie MellonToday Multitasking, shells Signals Long jumps More on signalsCarnegie MellonSignals A signal is a small message that notifies a process that an event of some type has occurred in the system akin to exceptions and interrupts sent from the kernel (sometimes at the request of another process) to a process signal type is identified by small integer ID’s (1-30) only information in a signal is its ID and the fact that it arrivedID Name Default Action Corresponding Event2 SIGINT Terminate Interrupt (e.g., ctl-c from keyboard)9 SIGKILL Terminate Kill program (cannot override or ignore)11 SIGSEGV Terminate & Dump Segmentation violation14 SIGALRM Terminate Timer signal17 SIGCHLD Ignore Child stopped or terminatedCarnegie MellonSending a Signal Kernel sends (delivers) a signal to a destination process by updating some state in the context of the destination process Kernel sends a signal for one of the following reasons: Kernel has detected a system event such as divide-by-zero (SIGFPE) or the termination of a child process (SIGCHLD) Another process has invoked the kill system call to explicitly request the kernel to send a signal to the destination processCarnegie MellonReceiving a Signal A destination process receives a signal when it is forced by the kernel to react in some way to the delivery of the signal Three possible ways to react: Ignore the signal (do nothing) Terminate the process (with optional core dump) Catch the signal by executing a user-level function called signal handler Akin to a hardware exception handler being called in response to an asynchronous interruptCarnegie MellonSignal Concepts (continued) A signal is pending if sent but not yet received There can be at most one pending signal of any particular type Important: Signals are not queued If a process has a pending signal of type k, then subsequent signals of type k that are sent to that process are discarded A process can block the receipt of certain signals Blocked signals can be delivered, but will not be received until the signal is unblocked A pending signal is received at most onceCarnegie MellonSignal Concepts Kernel maintains pending and blocked bit vectors in the context of each process pending: represents the set of pending signals Kernel sets bit k in pending when a signal
View Full Document