March 20, 2006
Coverage:
[USP] Chapter 8
Orientation
- concurrency and communication have been the two predominant
themes in this course
- we have used functions such as fork, wait,
and exec to achieve concurrency
- we have used input and output through pipes as our main
interprocess communication mechanism
- signals will provide an additional way to
foster interprocess communication, and it will be asynchronous
Signals: the Basics
- a signal is a software notification to a
process of an event
- the event generates the signal ([USP] §8.2)
- the signal is delivered when the process takes action
([USP] §8.5)
- the process must be in the running state
- the lifetime of the signal is the time
between the signal generation and delivery
- a signal which has been generated, but not yet
delivered, is said to be pending
- what is the difference between a signal and an interrupt?
- every signal is associated with a mnemonic starting with SIG
- represent small integers greater than 0
- defined in signal.h
- SIGUSR1 and SIGUSR2 are reserved for users
- the process signal mask
is the list of signals that the process is currently blocking
([USP] §8.3)
- blocking != ignoring
- a blocked signal is not thrown away
- it is delivered when unblocked
- use sigprocmask to change the
process signal mask (block the signal)
- a process can catch a signal by executing a
signal handler on signal delivery ([USP] §8.4)
- a program installs a signal handler by calling
sigaction with the name of a user-defined
function; or with
- SIG_DFL: default action
- SIG_IGN: ignore signal
neither are really considered to be catching the signal
Generating Signals
- use the UNIX command kill
- kill -s signame <PID> or kill [-signame] <PID>
- omit the leading SIG in the name
- kill [-signum] <PID>
- -2 (SIGINT; same as <ctrl-c>)
- -3 (SIGQUIT; same as <ctrl-\>)
- -9 (SIGKILL;
sure kill; process cannot inoculate itself against this signal)
- -15 (SIGTERM; default)
- kill -l # lists the available symbolic signal names
- int kill (pid_t pid, int sig);
- a user may only send a signal to processed that s/he owns
- how can a child process kill its parent?
- int raise (int sig);
- used to send a signal to yourself
- why might one ever desire to do this?
- unsigned alarm (unsigned seconds);
- requests to alarm are not stacked
- alarm never reports an error
Blocking Signals
- blocked signals do not affect the behavior of the
process until they are delivered
- signal mask gives the set of signals
which are currently blocked
- manipulated through 5 functions
- sigaddset, sigdelset, sigemptyset,
sigfillset, sigismember
- use sigprocmask to examine and/or modify
its process signal mask
- should only be used in a single-threaded program
- how parameter specifics how the
signal mask is to be modified
- SIG_BLOCK, SIG_UNBLOCK, SIG_SETMASK
- recall that SIGSTOP and SIGKILL cannot be blocked
- forked processes inherit the parent signal mask
- examples
- blocktest.c:
a program which blocks and unblocks SIGINT
- password.c: a function which blocks some
signals which, if delivered, might put the terminal
in an unusable state, during password entry
the sigaction Function
- used to get and/or set the action associated with a signal
- used like sigprocmask
- struct sigaction
- uses pointers to functions
- in POSIX, a signal handler is an ordinary function which
returns void and has one integer parameter
- on delivery, parameter set to the signal number
- two special values of sa_handler are
SIG_DFL and SIG_IGN
- SIG_DFL specifies that sigaction
should restore the default action
- SIG_IGN specifies that the
process should handle the signal by ignoring (discarding) it
- use write in signal handlers rather than
fprintf or strlen
- write is async-signal-safe
- means that it can be called safely from inside a
handler
- no such guarantees for fprintf or strlen
References
[USP] K. A. Robbins and S. Robbins. UNIX Systems Programming: Concurrency,
Communication, and Threads. Prentice Hall, 2003