Slide 1ECF Exists at All Levels of a SystemTodayThe World of MultitaskingProgrammer’s Model of MultitaskingShell ProgramsSimple Shell eval FunctionWhat Is a “Background Job”?Problem with Simple Shell ExampleECF to the Rescue!TodaySignalsSending a SignalReceiving a SignalSignal Concepts (continued)Signal ConceptsProcess GroupsSending Signals with kill ProgramSending Signals with kill FunctionReceiving SignalsDefault ActionsInstalling Signal HandlersSignal Handling ExampleSignals Handlers as Concurrent FlowsAnother View of Signal Handlers as Concurrent FlowsTodayNonlocal Jumps: setjmp/longjmpsetjmp/longjmp (cont)setjmp/longjmp ExampleLimitations of Nonlocal JumpsLimitations of Long Jumps (cont.)Slide 32SummaryTodaySending Signals from the KeyboardExample of ctrl-c and ctrl-zSignal Handler FunkinessLiving With Nonqueuing SignalsSignal Handler Funkiness (Cont.)A Program That Reacts to Externally Generated Events (Ctrl-c)A Program That Reacts to Internally Generated EventsCarnegie MellonIntroduction to Computer Systems15-213/18-243, spring 200915th Lecture, Mar. 5thInstructors: Gregory Kesden and Markus PüschelCarnegie MellonECF Exists at All Levels of a SystemExceptionsHardware and operating system kernel softwareSignalsKernel softwareNon-local jumpsApplication codePrevious LectureThis LectureCarnegie MellonTodayMultitasking, shellsSignalsLong jumpsMore on signalsCarnegie MellonThe World of MultitaskingSystem runs many processes concurrentlyProcess: executing programState includes memory image + register values + program counterRegularly switches from one process to anotherSuspend process when it needs I/O resource or timer event occursResume process when I/O available or given scheduling priorityAppears to user(s) as if all processes executing simultaneouslyEven though most systems can only execute one process at a timeExcept possibly with lower performance than if running aloneCarnegie MellonProgrammer’s Model of MultitaskingBasic functionsfork() spawns new processCalled once, returns twiceexit() terminates own processCalled once, never returnsPuts it into “zombie” statuswait() and waitpid() wait for and reap terminated childrenexecl() and execve() run new program in existing processCalled once, (normally) never returnsProgramming challengeUnderstanding the nonstandard semantics of the functionsAvoiding improper use of system resourcesE.g. “Fork bombs” can disable a systemCarnegie MellonShell ProgramsA 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” Shell int 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 timeType command, read output, type another commandSome programs run “for a long time”Example: “delete this file in two hours”% sleep 7200; rm /tmp/junk # shell stuck for 2 hoursA “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 ExampleShell correctly waits for and reaps foreground jobsBut what about background jobs?Will become zombies when they terminateWill never be reaped because shell (typically) will not terminateWill create a memory leak that could theoretically run the kernel out of memoryModern 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!ProblemThe shell doesn't know when a background job will finishBy nature, it could happen at any timeThe shell's regular control flow can't reap exited background processes in a timely fashionRegular control flow is “wait until running job completes, then reap it”Solution: Exceptional control flowThe kernel will interrupt regular processing to alert us when a background process completesIn Unix, the alert mechanism is called a signalCarnegie MellonTodayMultitasking, shellsSignalsLong jumpsMore on signalsCarnegie MellonSignalsA signal is a small message that notifies a process that an event of some type has occurred in the systemakin to exceptions and interruptssent from the kernel (sometimes at the request of another process) to a processsignal 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 SignalKernel sends (delivers) a signal to a destination process by updating some state in the context of the destination processKernel 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 SignalA destination process receives a signal when it is forced by the kernel to react in some way to
View Full Document