4061 Session 14 (3/1)
Today
• Signals
• Process Groups and Sessions
Today’s Objectives• Define a signal and explain its purpose
• Explain what happens in the operating system and in a user process when a signal is generated
• Write and read code to raise, catch, block, and ignore signals in C
• Understand process groups and sessions– Explain how a shell assigns process groups to
a pipeline of processes, and why
Admin
• Quiz 2: Answers online
• Quiz 3: Next Thursday
Killing Processes
• kill [ -s signal ] pid …
What’s Going on Here?
• Kill is sending a “signal” to the process
• A signal is the operating system telling a process to stop whatever it is doing and deal with a message– Thus, signals are asynchronous with the
process
• By default, the process terminates
• But we can override the default behavior
What are Signals Used For?
• Used by the OS to notify processes that an event has occurred
• This is nice because the process does not have to poll for events
Signal Types
• There are many signal types– man 7 signal
• Signals can be generated interactively with special chars in the terminal– ctrl-c: SIGINT (terminate)– ctrl-z: SIGTSTP (suspend)– Others defined: stty -a
• How do these keyboard-generated signals (asynchonously) find their way to the program immediately?
Signal Vocabulary
• A signal is generated when the event causing the signal occurs
• A signal is delivered when the process actually takes action
• Note: there can be real time between generation and delivery. (This gap is known as the signal’s lifetime)
• A process can catch a signal (by defining a signal handler), block a signal (queue the signal for later delivery), or ignore a signal (ignore the signal permanently).
Defaults
• If we don’t catch a signal, a default action takes place– abort– abort w/ core dump– stop– ignore
• Override the defaults by catching, blocking, or ignoring particular signals– Except SIGKILL and SIGSTOP: defaults cannot be
overridden
Sending Signals
• We’ve seen how to do it from the command line: kill– Exclude the “SIG” prefix for the signal name– E.g. kill -KILL 7236
• In C:– int kill(pid_t pid, int signal)– pid > 0: specified process id– pid == 0: current process group– pid == -1: all procs except init– pid < -1: process group -pid
Raising Signals
• Sending a signal to the current process is called “raising a signal”
int raise(int signal);• Just like: kill(getpid(), signal);• In a single-threaded program, raising a
signal is synchronous– If it’s not blocked or ignored, delivered before
next instruction
Blocking Signals
• Blocked signals remain pending until unblocked– Note: we can only remember last signal
• A pending signal is immediately delivered when unblocked
• int sigprocmask(int how, sigset_t *set, sigset_t *oldset)
• How is:– SIG_BLOCK– SIG_UNBLOCK– SIG_SETMASK
Signal Sets
• Manipulating signal sets– sigaddset– sigdelset– sigemptyset– sigfillset– sigismember
Handling Signals
• The easy way to do it is with “signal”sighandler_t signal(int signum, sighandler_t handler);
• But this way has some serious problems
• So, before we get to the more complex (and better) way, some more structure
sigaction
int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact);
struct sigaction { void (*sa_handler)(int);void (*sa_sigaction)(int, siginfo_t *, void *);sigset_t sa_mask;
int sa_flags; void (*sa_restorer)(void);}
Waiting for a Signal
• pause, sigsuspend, and sigwait
System Shutdown
• First send a TERM signal to all processes, wait for a grace period, then send a KILL signal.– KILL is a signal that cannot be handled
Signals
• More information: http://users.actcom.co.il/~choo/lupg/tutorials/signals/signals-programming.html#sending
Process Groups
• Used for the distribution of signals
• A process is always a member of a single process group
• A process group ID is the same as the PID of the group’s initial member– Thus, they share a “name space” with PIDs
• When created, each process is placed into the process group of its parent
Sessions
• A set of one or more process groups associated with a terminal
• Uses:– Group user terminal sessions together– Isolate daemons
• setsid
• A process can only join process groups in its own session
Shells and Process Groups
• Shells, though, create new process groups, placing related processes (e.g. those connected with a pipe) into the same group
• Steps (for first process in pipeline):– Fork (initially has same PG ID as the shell)– Child issues setpgid() to set its PG ID = PID, creating
a new process group. Child is now a “process leader”– Redirect I/O to pipe– Exec
• Subsequent processes in pipeline:– Same, but children set their PG ID to that of the first
child
Some Shell Tricks
• What if the parent creates the second child in the pipeline before the first child becomes the session leader?
• What if the first child exits before the second child issues setpgid?
Process Groups
• Read Robbins 11.5
• Additional Reading– Process Groups in BSD: http://
www.informit.com/articles/article.asp?p=366888&seqNum=8&rl=1