recitation 7 (oct. 25)

25
Recitation 7 (Oct. 25) Outline Exceptions Process Signals Non-local jumps Reminders Lab4: Due Thursday Minglong Shao [email protected] Office hours: Thursdays 5-6PM Wean Hall 1315

Upload: athena-higgins

Post on 01-Jan-2016

39 views

Category:

Documents


1 download

DESCRIPTION

Outline Exceptions Process Signals Non-local jumps Reminders Lab4: Due Thursday. Minglong Shao [email protected] Office hours: Thursdays 5-6PM Wean Hall 1315. Recitation 7 (Oct. 25). Exceptional control flow (ECF). Abrupt changes in the control flow - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: Recitation 7 (Oct. 25)

Recitation 7 (Oct. 25)

Outline Exceptions Process Signals Non-local jumps

Reminders Lab4:

Due Thursday

Minglong [email protected]

Office hours:Thursdays 5-6PMWean Hall 1315

Page 2: Recitation 7 (Oct. 25)

Exceptional control flow (ECF)

Abrupt changes in the control flow React to changes in system state that are not

captured by internal program variables and are not necessarily related to the execution of the program

Happens at all levels of a computer system Exceptions Concurrent processes Signals Non-local jumps

Page 3: Recitation 7 (Oct. 25)

Exceptions

Interrupt (asynchronous exceptions) I/O interrupt, hardware reset, software reset, etc.

Traps System calls, breakpoint traps, etc.

Faults Page fault, protection fault, etc.

Aborts Parity error, machine check, etc.

Page 4: Recitation 7 (Oct. 25)

Process concept

An instance of running program Multiple processes run “concurrently” by time

slicing Context switching

Control flow passes from one process to another Preemptive scheduler of OS

Page 5: Recitation 7 (Oct. 25)

Process IDs & process groups A process has its own, unique process ID

pid_t getpid();

A process belongs to exactly one process group pid_t getpgrp();

A new process belongs to which process group? Its parent’s process group

A process can make a process group for itself and its children pid_t pid = getpid(); setpgid(0, 0); getpgrp()

Page 6: Recitation 7 (Oct. 25)

Create a new process

int fork(void) Create a new process that is identical to the

parent process Return 0 to child process Return child’s pid to the parent process Call once, return twice

Test your understanding… Problem 1

Page 7: Recitation 7 (Oct. 25)

Problem 1#include <unistd.h>#include <stdio.h>

int cnt = 0;

int main(void){ if (fork() == 0){ cnt ++; fork(); cnt++; } cnt ++; printf("%d", cnt); return 0;}

Possible output:133313331

Page 8: Recitation 7 (Oct. 25)

Reaping child process

Child process becomes zombie when terminates Still consume system resources Parent performs reaping on terminated childpid_t wait(int *status)

pid_t waitpid(pid_t pid, int *status, int options)

Straightforward for reaping a single child Tricky for Shell implementation!

Multiple child processes Both foreground and background

Practice time again: problem 2

Page 9: Recitation 7 (Oct. 25)

Problem 2int main(){ int status; int counter = 1; if (fork() == 0){ counter ++; printf("%d", counter); }else { if (fork() == 0){ printf("9"); counter --; printf("%d", counter); exit(0); }else { if (wait(&status) > 0){ printf("6"); } } } printf("8"); exit(0);}

Answers:A. YB. NC. YD. NE. Y

Page 10: Recitation 7 (Oct. 25)

Signals

Section 8.5 in text Read at least twice … really!

A signal tells our program that some event has occurred

Can we use signals to count events? No Why? Signals not queued!!

Page 11: Recitation 7 (Oct. 25)

Important signals (Fig 8.23)

SIGINT Interrupt signal from terminal (ctrl-c)

SIGTSTP Stop signal from terminal (ctrl-z)

SIGCHLD A child process has stopped or terminated

Page 12: Recitation 7 (Oct. 25)

Signals: sending

OS Kernel

blockedpending1

Process 1 Process 2

other events

OS procedure

kill(pid, SIGINT)

• divide by zero: SIGFPE

• ctrl-c: SIGINT

• child process exit: SIGCHLD

Page 13: Recitation 7 (Oct. 25)

Signals: receiving

OS Kernel

blockedpending1

Process 2

OS procedure

0

Check when schedule the process to run

Page 14: Recitation 7 (Oct. 25)

Receiving a signal

Default action The process terminates [and dumps core] The process stops until restarted by a SIGCONT

signal (ctrl-z) The process ignore the signal

Can modify (additional action) “Handle the signal” -- install signal handler

void sigint_handler(int sig);

signal(SIGINT, sigint_handler);

An example: problem 3

Page 15: Recitation 7 (Oct. 25)

Problem 3void handler(int sig){ static int beeps = 0; printf("YO\n"); if (++beeps < 2) alarm(1); /* next SIGALRM will be delivered in 1s */ else{ printf("MA\n"); kill(getpid(), SIGKILL); }}

int main(){ Signal(SIGALRM, handler); alarm(1); /* next SIGALRM will be delivered in 1s */ while (1) ; printf(" is Great!\n"); return 0;}

1. Output:YOYOMA2. The program will terminate

Page 16: Recitation 7 (Oct. 25)

Signals not queuedint counter = 0;void handler(int sig){ counter++; sleep(1); return;}

int main(){ int i; signal(SIGUSER2, handler); if (fork() == 0){ for (i = 0; i < 5; i++){ kill(getppid(), SIGUSR2); printf(“sent SIGUSR2 to parent\n”); } exit(0); } wait(NULL); printf(“counter = %d\n”, counter); exit(0);}

Output:sent SIGUSR2 to parentsent SIGUSR2 to parentsent SIGUSR2 to parentsent SIGUSR2 to parentsent SIGUSR2 to parentcounter = 1

Page 17: Recitation 7 (Oct. 25)

Race hazard

A data structure is shared by two pieces of code that can run concurrently

Different behaviors of program depending upon how the schedule interleaves the execution of code.

Page 18: Recitation 7 (Oct. 25)

An example of race hazard

sigchld_handler() { pid = waitpid(…); deletejob(pid);}eval() { pid = fork(); if(pid == 0) { /* child */ execve(…); } /* parent */ /* signal handler may run BEFORE addjob()*/ addjob(…);}

Page 19: Recitation 7 (Oct. 25)

An okay schedule

Shell Signal Handler Child

fork()

addjob()

execve()

exit()

sigchld_handler()

deletejobs()

time

Page 20: Recitation 7 (Oct. 25)

A problematic schedule

Shell Signal Handler Child

fork()

execve()

exit()

sigchld_handler()

deletejobs()

time

addjob()

Job added to job list after the signal handler tried to delete it!

Page 21: Recitation 7 (Oct. 25)

Solution: blocking signalssigchld_handler() { pid = waitpid(…); deletejob(pid);}eval() { sigprocmask(SIG_BLOCK, …) pid = fork(); if(pid == 0) { /* child */ sigprocmask(SIG_UNBLOCK, …) execve(…); } /* parent */ /* signal handler might run BEFORE addjob() */ addjob(…); sigprocmask(SIG_UNBLOCK, …)}

More details 8.5.6 (page 633)

Page 22: Recitation 7 (Oct. 25)

Non-local jump

int setjmp(jmp_buf env) Must called before longjmp Stores current register context, stack pointer, and PC in

the jump buffer env First called, return 0 if no error

void longjmp(jmp_buf env, int i) Restores register context from jump buffer env Jumps back to where previous setjmp is called, behaves

like setjmp just completes. But this time it returns i, not 0

Can only jump to an active context A function that has been called but not yet

completed

Page 23: Recitation 7 (Oct. 25)

Non-local jump (cont)

int sigsetjmp(jmp_buf env) Also saves blocked signals

void siglongjmp(jmp_buf env, int i) Restores blocked signals besides others

Let’s see an example: problem 4

Page 24: Recitation 7 (Oct. 25)

Problem 4jmp_buf stuff;jmp_buf more_stuff;

int bar(){ if (setjmp(more_stuff) == 0) return 3; else return 6;}

int foo(){ char c = getc(stdin); if (c == 'x') longjmp(stuff, 42); else if (c == 'y') longjmp(more_stuff, 17); else return bar(); return -1;}

int main(){ int n; n = setjmp(stuff); while ((n+=foo())<0) sleep(1); printf("%d\n", n);}

Answer:1. 32. 453. 454. ?5. ?

Page 25: Recitation 7 (Oct. 25)

Summary

Process fork(), waitpid(), execl() (and variant)

Reaping child processes Signals

signal(), install handler, signals not queued Non-local jumps Check man page to understand the system calls

better man waitpid (fork, signal, …)

Read test book!