Transcript signal

Lab #8
Signals
Operating System Lab
NCHU System & Network Lab
What Are Signals?
• A signal is used by the OS to notify a process that a
particular event has occurred.
• All signals follow the same pattern:
– A signal is generated by the occurrence of a particular event.
– A generated signal is delivered to a process.
– Once delivered, the signal must be handled.
• Every signal may be handled by one of two possible
handlers:
– A default signal handler
– A user-defined signal handler
NCHU System & Network Lab
Generating Signals
• Every signal has a symbolic name starting with
SIG.
• The signal names are defined in signal.h
• Each signal is represented by small integers greater
than 0.
NCHU System & Network Lab
Generating Signals
NCHU System & Network Lab
Generating Signals (cont.)
NCHU System & Network Lab
Sending Signals
• Using the keyboard
– There are certain key presses that are interpreted by the system as requests to
send signals to the process.
• Ctrl-C
– Causes the system to send an INT signal (SIGINT) to the running process.
By default, this signal causes the process to immediately terminate.
• Ctrl-Z
– Causes the system to send a TSTP signal (SIGTSTP) to the running process.
By default, this signal causes the process to suspend execution.
• Ctrl-\
– Causes the system to send a ABRT signal (SIGABRT) to the running process.
By default, this signal causes the process to immediately terminate.
NCHU System & Network Lab
Sending Signals (cont.)
• From the command line
SYNOPSIS
kill -s signal_name pid
kill [-signal_name] pid
kill [-signal_number] pid
• signal_name: a symbolic name for the signal formed by
omitting the leading SIG from the corresponding symbolic
signal name.
• If no signal_name is specified, the TERM signal is sent.
NCHU System & Network Lab
Example
• The following command is the traditional way to send signal number 9
(SIGKILL) to process 3423.
– kill -9 3423
• The following command sends the SIGUSR1 signal to process 3423.
– kill -s USR1 3423
• The following command sends the INT signal to process 3423.
– kill -INT 3423
• The following command sends the TERM signal to process 3423, and
therefore the process 3423 is terminated.
– kill 3423
NCHU System & Network Lab
Sending Signals (cont.)
• Using system calls
– This is the normal way of sending a signal from one
process to another.
SYNOPSIS
#include <signal.h>
int kill(pid_t pid, int sig);
Return 0 if successful, -1 if unsuccessful
• Example: A child process sends the SIGTERM
signal to its parent process.
– kill(getppid(), SIGTERM);
NCHU System & Network Lab
alarm() Function
• Causes a SIGALRM signal to be sent to the calling process
after a specified number of real seconds has elapsed.
• A value of seconds of 0 will turn off the timer.
• Calling alarm() before the signal is received will cause the
alarm to be rescheduled.
SYNOPSIS
#include <unistd.h>
unsigned alarm(unsigned seconds);
NCHU System & Network Lab
Catching and Ignoring Signals
• What is a signal handler?
– The function to handle a signal.
• Default Signal Handlers
– If you install no signal handlers of your own, the runtime
environment sets up a set of default signal handlers for
your program.
– For example, the default signal handler for the TERM
signal calls the exit()system call.
NCHU System & Network Lab
Catching and Ignoring Signals (cont.)
• Installing Signal Handlers
– signal(), sigaction()
• signal: is used to set a signal handler for a single signal type.
SYNOPSIS
#include <signal.h>
void (*signal(int sig, void (*func)(int)))(int);
• pause: causes the process to halt execution, until a signal is
received. It is surely better than a 'busy wait' infinite loop.
SYNOPSIS
#include <unistd.h>
int pause(void);
Catching and Ignoring Signals (cont.)
• Example
/* here is the signal handler */
void catch_int(int sig_num)
{
/* the argument is signal number */
/* re-set the signal handler again to catch_int, for next time */
signal(SIGINT, catch_int);
printf(“Ouch! – I got signal %d\n");
}
int main(int argc, char* argv[])
{
/* set the INT (Ctrl-C) signal handler to 'catch_int' */
signal(SIGINT, catch_int);
/* now, lets get into an infinite loop of doing nothing. */
for ( ;; )
pause();
}
NCHU System & Network Lab
Catching and Ignoring Signals (cont.)
• Pre-defined Signal Handlers: We can use two pre-defined
signal handler functions, instead of writing our own.
– SIG_IGN: Ignore the specified signal.
– SIG_DFL: Restore default behavior.
• One problem with the early versions of UNIX is that
the action of a signal was reset to its default each
time the signal occurred.
NCHU System & Network Lab
Exercise
• Write a simple signal handler that catches either of the two
user defined signals and prints the signal number.
• Put the process to sleep until a signal is received.
• Then, we invoke the program in the background and use the
kill command to send it signals.
NCHU System & Network Lab
Catching and Ignoring Signals (cont.)
• sigaction: allows the caller to examine or specify the
action associated with a specific signal.
SYNOPSIS
#include <signal.h>
int sigaction(int sig, const struct sigaction *act, struct sigaction *oact);
Return 0 if successful, -1 if unsuccessful
• The sigaction structure, used to define the actions to be taken
on receipt of the signal specified by sig.
struct sigaction {
void (*) (int) sa_handler;
/* pointer to function, SIG_DFL or SIG_IGN */
sigset_t sa_mask; /* additional signals to be blocked during execution of handler */
int sa_flags;
/* signal action modifiers */
}
NCHU System & Network Lab
Catching and Ignoring Signals (cont.)
• sig: specifies the signal number for the action
• act: a pointer to a struct sigaction structure that specifies
the action to be taken
– If act is NULL, the call to sigaction() does not change
the action associated with the signal.
• oact: a pointer to a struct sigaction structure that receives
the previous action associated with the signal
– If oact is NULL, the call to sigaction() does not return
the previous action associated with the signal.
NCHU System & Network Lab
Catching and Ignoring Signals (cont.)
• sa_flags
– signals caught with handlers set by sigaction() are by
default not reset.
– the sa_flags field must be set to contain the value
SA_RESETHAND if we wish to obtain the behavior we saw
earlier with signal.
NCHU System & Network Lab
Examples
1. The following code segment sets the signal handler for SIGINT to mysighand.
struct sigaction newact;
newact.sa_handler = mysighand;
sigemptyset(&newact.sa_mask);
newact.sa_flags = 0;
/* set the new handler */
/* initialize the signal mask */
/* no special options */
sigaction(SIGINT, &newact, NULL);
2. The following code segment causes the process to ignore SIGINT if the default
action is in effect for this signal.
struct sigaction act;
sigaction(SIGINT, NULL, &act);
/* Find current SIGINT handler */
if (act.sa_handler == SIG_DFL) { /* if SIGINT handler is default */
act.sa_handler = SIG_IGN;
/* set new SIGINT handler to ignore */
sigaction(SIGINT, &act, NULL);
}
NCHU System & Network Lab
Signal Masks and Signal Sets
• A process can temporarily prevent a signal from being delivered by
blocking it.
• This signal mask is the set of signals that are currently
blocked and therefore not be received by the current process.
• The signal mask is of type sigset_t.
• Blocking a signal is different from ignoring a signal.
– When a process blocks a signal, the operating system does not
deliver the signal until the process unblocks the signal.
– A process blocks a signal by modifying its signal mask with
sigprocmask.
– When a process ignores a signal, the signal is delivered and the
process handles it by throwing it away.
NCHU System & Network Lab
Signal Masks and Signal Sets (cont.)
• Functions used to manipulate sets of signals:
SYNOPSIS
#include <signal.h>
int sigaddset(sigset_t *set, int signo);
// adds signo to the signal set
int sigdelset(sigset_t *set, int signo);
// removes signo from the signal set
int sigemptyset(sigset_t *set);
// initializes a sigset_t to contain no signals
int sigfillset(sigset_t *set);
// initializes a sigset_t to contain all signals.
int sigismember(sigset_t *set, int signo); // reports whether signo is in a sigset_t.
NCHU System & Network Lab
Example
/* define a new mask set */
sigset_t mask_set;
/* first clear the set (i.e. make it contain no signal numbers) */
sigemptyset(&mask_set);
/* lets add the TSTP and INT signals to our mask set */
sigaddset(&mask_set, SIGTSTP);
sigaddset(&mask_set, SIGINT);
/* and just for fun, lets remove the TSTP signal from the set. */
sigdelset(&mask_set, SIGTSTP);
/* finally, lets check if the INT signal is defined in our set */
if(sigismember(&mask_set, SIGINT)
printf("signal INT is in our set\n");
else
printf("signal INT is not in our set - how strange...\n");
/* finally, lets make the set contain ALL signals available on our system */
sigfillset(&mask_set)
NCHU System & Network Lab
Signal Masks and Signal Sets (cont.)
• A process can examine or modify its process signal mask with the
sigprocmask fuction.
SYNOPSIS
#include <signal.h>
int sigprocmask(int how, const sigset_t *set, sigset_t *oset);
• how: specifies the manner in which the signal mask is to be
modified, can take on one of the following three values.
– SIG_BLOCK: The signals in set are added to the signal mask.
– SIG_UNBLOCK: The signals in set are removed from the signal mask.
– SIG_SETMASK: The signal mask is set from set.
NCHU System & Network Lab
Signal Masks and Signal Sets (cont.)
• set: a pointer to a signal set to be used in the modification.
– If set is NULL, no modification is made.
• oset: If oset is not NULL, the sigprocmask returns in oset
the signal set before the modification.
• Example
sigset_t new_set;
sigprocmask(SIG_SETMASK,&new_set,NULL); // The signal mask is set from new_set
The following code segment adds SIGINT to the set of signals that the process has blocked.
sigset_t new_set;
sigemptyset(&new_set);
sigaddset(&new_set, SIGINT);
sigprocmask(SIG_BLOCK, &new_set, NULL);
Lab I – An Alarm Clock
• Object: To simulate an alarm clock.
• First, we use fork() to create another process.
• The child process waits for five seconds before sending a
SIGALRM signal to its parent.
– hint: sleep(nsec) halts process in nsec seconds.
• The parent process catches SIGALRM by first installing a
signal handler using sigaction()and then waits for the
sure occurrence of the signal.
NCHU System & Network Lab
Lab II – Blocking and Unblocking a
signal
• First, we block the SIGINT signal and increment the
variable y eight times.
– wait for one second between each calculation.
• Then, unblock the signal, and do it the same times.
• The program repeats this sequence continually in a
loop.
NCHU System & Network Lab
Lab II – Blocking and Unblocking a
signal
NCHU System & Network Lab
References
• Avi Silberschatz, Peter Baer Galvin and Greg Gagne, “Operating
System Concepts,” John Wiley & Sons, 6th Edition, 2001
• “Unix Systems Programming: Communication, Concurrency, and
Threads” by Kay A. Robbins, Steven Robbins
• Neil Matthew and Richard Stones, “Beginning Linux Programming,”
Wiley publishing, 3rd Edition, 2004
• W. Richard Stevens, “Advanced Programming in the UNIX
Environment,” Addison-Wesley, 1992
• http://users.actcom.co.il/~choo/lupg/tutorials/signals/signalsprogramming.html
NCHU System & Network Lab