Presentation is loading. Please wait.

Presentation is loading. Please wait.

Copyright ©: Nahrstedt, Angrave, Abdelzaher1 Signals.

Similar presentations


Presentation on theme: "Copyright ©: Nahrstedt, Angrave, Abdelzaher1 Signals."— Presentation transcript:

1 Copyright ©: Nahrstedt, Angrave, Abdelzaher1 Signals

2 Copyright ©: Nahrstedt, Angrave, Abdelzaher 2 Introduction to Signals What is Signal? A signal is a software notification to a process of an event. Why do we need Signals? In systems we need to enable asynchronous events Examples of asynchronous events: Email message arrives on my machine – mailing agent (user) process should retrieve Invalid memory access happens – OS should inform scheduler to remove process from the processor Alarm clock goes on – process which sets the alarm should catch it

3 Copyright ©: Nahrstedt, Angrave, Abdelzaher 3 How Signals Work Signal Generated Process Signal Handler Signal delivered Signal not blocked Signal Caught by handler Return from Signal Handler Process Resumed Signal Mask Signal Mask Signal Mask

4 Copyright ©: Nahrstedt, Angrave, Abdelzaher 4 Examples of POSIX Required Signals SignalDescriptiondefault action SIGABRTprocess abortimplementation dependent SIGALRMalarm clockabnormal termination SIGBUSaccess undefined part of memory objectimplementation dependent SIGCHLDchild terminated, stopped or continuedignore SIGILLinvalid hardware instructionimplementation dependent SIGINTinteractive attention signal (usually ctrl-C) abnormal termination SIGKILLterminated (cannot be caught or ignored) abnormal termination

5 Copyright ©: Nahrstedt, Angrave, Abdelzaher 5 SignalDescriptiondefault action SIGSEGVInvalid memory referenceimplementation dependent SIGSTOPExecution stoppedstop SIGTERMterminationAbnormal termination SIGTSTPTerminal stopstop SIGTTINBackground process attempting readstop SIGTTOUBackground process attempting writestop SIGURGHigh bandwidth data available on socket ignore SIGUSR1User-defined signal 1abnormal termination Examples of POSIX Required Signals

6 Copyright ©: Nahrstedt, Angrave, Abdelzaher 6 Generating Signals Signal has a symbolic name starting with SIG Signal names are defined in signal.h Users can generate signals (e.g., SIGUSR1) OS generates signals when certain errors occur (e.g., SIGSEGV – invalid memory reference) Specific calls generate signals such as alarm (e.g., SIGALRM)

7 Copyright ©: Nahrstedt, Angrave, Abdelzaher 7 Command Line Generates Signals You can send a signal to a process from the command line using kill kill -l will list the signals the system understands kill [-signal] pid will send a signal to a process. The optional argument may be a name or a number (default is SIGTERM). To unconditionally kill a process, use: kill -9 pid which is kill -SIGKILL pid.

8 Copyright ©: Nahrstedt, Angrave, Abdelzaher 8 Command Line Generates Signals CTRL-C is SIGINT (interactive attention signal CTRL-Z is SIGSTOP (execution stopped – cannot be ignored) CTRL-Y is SIGCONT (execution continued if stopped) CTRL-D is SIGQUIT (interactive termination: core dump)

9 Copyright ©: Nahrstedt, Angrave, Abdelzaher 9 Timers Generate SIGALRM Signals #include unsigned alarm (unsigned seconds); alarm(20) creates SIGALRM to calling process after 20 real time seconds. Calls are not stacked alarm(0) cancels alarm

10 Copyright ©: Nahrstedt, Angrave, Abdelzaher 10 Examples: Programming Signals From a program you can use the kill system call: #include int kill(pid_t pid, int sig); Example 8.4: send SIGUSR1 to process 3423: if (kill(3423, SIGUSR1) == -1) perror("Failed to send the SIGUSR1 signal"); Example 8.5: a child kills its parent: if (kill(getppid(), SIGTERM) == -1) perror ("Failed to kill parent");

11 Copyright ©: Nahrstedt, Angrave, Abdelzaher 11 Programming Signals Example 8.5: a process sends a signal to itself: if (raise(SIGUSR1) != 0) perror("Failed to raise SIGUSR1"); Example 8.8: kill an infinite loop after 10 seconds: int main(void) { alarm(10); for ( ; ; ) ; }

12 Copyright ©: Nahrstedt, Angrave, Abdelzaher 12 Signal Masks Process can temporarily prevent signal from being delivered by blocking it. Signal Mask contains a set of signals currently blocked. Important! Blocking a signal is different from ignoring signal. Why? When a process blocks a signal, the OS does not deliver signal until the process unblocks the signal A blocked signal is not delivered to a process until it is unblocked. When a process ignores signal, signal is delivered and the process handles it by throwing it away.

13 Copyright ©: Nahrstedt, Angrave, Abdelzaher 13 Signal Sets Signal set is of type sigset_t Signal sets are manipulated by five functions: #include int sigemptyset(sigset_t *set); int sigfillset(sigset_t *set); int sigaddset(sigset_t *set, int signo); int sigdelset(sigset_t *set, int signo); int sigismember(const sigset_t *set, int signo);

14 Copyright ©: Nahrstedt, Angrave, Abdelzaher 14 Signal Sets sigemptyset initializes the set to contain no signals sigfillset puts all signals in the set sigaddset adds one signal to the set sigdelset removes one signal from the set sigismember tests to see if a signal is in the set

15 Copyright ©: Nahrstedt, Angrave, Abdelzaher 15 Signal Masks SigIntSigQuitSigKill…SigContSigAbrt 001…10 SigMask Signal SigInt Bit 2, Signal Sigkill Bit 9, Signal SigChld Bit 20 A SIGSET is a collection of signals: #000003 is SIGHUP + SIGINT

16 Copyright ©: Nahrstedt, Angrave, Abdelzaher 16 SIGPROCMASK The function sigprocmask is used to modify the signal mask. #include int sigprocmask(int how, const sigset_t *restrict set, sigset_t *restrict oset) ‘how’ specifies the manner in which the signal mask is to be modified SIG_BLOCK – add collection of signals to those currently blocked SIG_UNBLOCKED – delete collection of signals from the currently blocked SIG_SETMASK – set collection of signals being blocked to the specified set

17 Copyright ©: Nahrstedt, Angrave, Abdelzaher 17 Example: Initialize Signal Set: if ((sigemptyset(&twosigs) == -1) || (sigaddset(&twosigs, SIGINT) == -1) || (sigaddset(&twosigs, SIGQUIT) == -1)) perror("Failed to set up signal mask");

18 Copyright ©: Nahrstedt, Angrave, Abdelzaher 18 Example: Add SIGINT to Set of Blocked Signals sigset_t newsigset; if ((sigemptyset(&newsigset) == -1) || (sigaddset(&newsigset, SIGINT) == -1)) perror("Failed to initialize the signal set"); else if (sigprocmask(SIG_BLOCK, &newsigset, NULL) == -1) perror("Failed to block SIGINT"); If SIGINT is already blocked, the call to sigprocmask has no effect.

19 Copyright ©: Nahrstedt, Angrave, Abdelzaher 19 Catching and Ignoring Signals - SIGACTION sigaction function allows the caller to examine or specify action associated with a specific signal Program installs signal handler by calling sigaction with the name of a user- written function. The function sigaction is used to specify what is to happen to a signal when it is delivered.

20 Copyright ©: Nahrstedt, Angrave, Abdelzaher 20 #include int sigaction(int signo, const struct sigaction *act, struct sigaction *oact); struct sigaction { void (*sa_handler)(int); /* SIG_DFL, SIG_IGN or pointer to function */ sigset_t sa_mask; /* additional signals to be blocked during execution of handler */ int sa_flags; /*special flags and options */ void(*sa_sigaction) (int, siginfo_t *, void *); /* real-time handler */ }; 1. Either act or oact may be NULL. 2. If SA_SIGINFO flag of sa_flags field is clear, sa_handler specifies the action to be taken. Catching and Ignoring Signals - SIGACTION

21 Copyright ©: Nahrstedt, Angrave, Abdelzaher 21 Example: Set up Signal Handler for SIGINT struct sigaction newact; newact.sa_handler = mysighand; /*set new handler*/ newact.sa_flags = 0; /* no special options */ if ((sigemptyset(&newact,sa_mask) == -1) || (sigaction(SIGINT, &newact, NULL) == -1)) perror(“Failed to install SIGINT signal handler”);

22 Copyright ©: Nahrstedt, Angrave, Abdelzaher 22 Set up Signal Handler that Catches SIGINT Generated by Ctrl-C void catchctrlc(int signo) { char handmsg[] = "I found Ctrl-C\n"; int msglen = sizeof(handmsg); write(STDERR_FILENO, handmsg, msglen); } … struct sigaction act; act.sa_handler = catchctrlc; act.sa_flags = 0; if ((sigemptyset(&act.sa_mask) == -1) || (sigaction(SIGINT, &act, NULL) == -1)) perror("Failed to set SIGINT to handle Ctrl-C"); Note: write is async-signal safe – meaning it can be called inside a signal handler. Not so for printf or strlen.

23 Copyright ©: Nahrstedt, Angrave, Abdelzaher 23 Waiting for Signals Signals provide method for waiting for event without busy waiting Busy waiting Means continually using CPU cycles to test for occurrence of event Means a program does this testing by checking the value of variable in loop More Efficient Approach Suspend process until waited-for event occurs POSIX pause, sigsuspend, sigwait provide three mechanisms to suspend process until signal occurs pause() – too simple, and problematic if signals are delivered before pause (cannot unblock the signal and start pause() in atomic way)

24 Copyright ©: Nahrstedt, Angrave, Abdelzaher 24 sigsuspend sigsuspend function sets signal mask and suspends process until signal is caught by the process sigsuspend returns when signal handler of the caught signal returns #include int sigsupend(const sigset_t *sigmask);

25 Copyright ©: Nahrstedt, Angrave, Abdelzaher 25 Example: sigsuspend What’s wrong? sigfillset(&sigmost); sigdelset(&sigmost, signum); sigsuspend(&sigmost); signum is the only signal unblocked that can cause sigsuspend to return If the signal signum is delivered before the start of the code segment, the process still suspends itself and deadlocks if another signum is not generated

26 Copyright ©: Nahrstedt, Angrave, Abdelzaher 26 Example: sigsuspend (Correct Way to Wait for Single Signal) static volatile sig_atomic_t sigreceived =0; /*assume signal handler has been setup for signum and it sets sigreceived=1 */ sigset_t maskall, maskmost, maskold; int signum = SIGUSR1; sigfillset(&maskall); sigfillset(&maskmost); sigdelset(&maskmost, signum); sigprocmask(SIG_SETMASK, &maskall, &maskold); if (sigreceived == 0) sigsuspend(&maskmost); sigprocmask(SIG_SETMASK, &maskold, NULL);

27 Copyright ©: Nahrstedt, Angrave, Abdelzaher 27 Use sigwait This function is much cleaner and avoids races and errors !!!! 1. First block all signals 2. Put the signals you want to wait for in sigset_t 3. Call sigwait 4. sigwait blocks the process until at least one of these signals is pending. 5. It removes one of the pending signals and gives you the corresponding signal number in the second parameter.. 6. Do what you want: no signal handler needed. 7. It returns 0 on success and -1 on error with errno set. #include int sigwait(const sigset_t *restrict sigmask, int *restrict signo);


Download ppt "Copyright ©: Nahrstedt, Angrave, Abdelzaher1 Signals."

Similar presentations


Ads by Google