Lienhua34
2014-11-03
1 Signal Transfer process
The signal source generates a signal for the target process, which is then determined by the kernel to pass the signal to the target process. From the signal generation to the flow to the target process, flowchart 1 shows that
Figure 1: Flowchart for signal generation, transmission to processing
Processes can block the transmission of signals. Once the signal source has generated a signal for the target process, the kernel performs the following operations in turn,
1. If the target process is set to ignore the signal, the kernel discards the signal directly.
2. If the target process does not block the signal, the kernel passes the signal to the target process and the target process performs the relative action.
3. If the target process setting blocks the signal, the kernel places the signal in the blocked signal list of the target process, waiting for the target process to set up the signal for that type. If subsequent settings of the target process ignore the signal, the kernel removes the signal from the blocked signal list of the target process and discards it. If the target process is blocking the signal, the kernel passes the signal to the target process for the corresponding operation.
We call this signal pending (pending) during the time interval between signal generation and signal transmission to the target process.
Each process has a signal-blocking word (signal mask) that specifies the set of signals that are currently being blocked for delivery to the process. For each possible signal, one of the signal shielding words corresponds to it.
2 signal set and its operation
POSIX.1 defines a data type sigset_t, which is used to represent the signal set. In addition, the header file Signal.h provides the following five functions for processing a signal set.
The function Sigemptyset initializes the set of signals that the set points to, clearing all of the signals.
int Sigemptyset (sigset_t *set);
Return value: Returns 0 if successful, or 1 if an error occurs
The function Sigfillset initializes the set of signals that the set points to, which contains all the signals.
int Sigfillset (sigset_t *set);
Return value: Returns 0 if successful, or 1 if an error occurs
The function Sigaddset adds a signal signo to the existing set of signal sets.
int Sigaddset (sigset_t *set, int signo);
Return value: Returns 0 if successful, or 1 if an error occurs
The function Sigdelset removes a signal signo from the set of signals.
int Sigdelset (sigset_t *set, int signo);
Return value: Returns 0 if successful, or 1 if an error occurs
The function Sigismember determines whether the specified signal Signo is in the set of the signal sets.
int Sigismember (const sigset_t *set, int signo);
Return value: Returns 1 if true, returns 0 if False, or 1 if an error occurs
3. Sigprocmask check or set the signal screen word of the process
Call the Sigprocmask function to detect or set the signal screen word of the process.
#include <signal.h>
int sigprocmask (int how, const sigset_t *restrict set, sigset_t *restrict oset);
Return value: Returns 0 if successful, or 1 if an error occurs
If the Oset parameter is a non-null pointer, the current signal screen word of the process is returned through Oset. If the set parameter is a non-null pointer, the parameter how will indicate how to modify the current signal mask word. The optional values of how are shown in table 1,
Table 1:sigprocmask function how parameter optional value
How |
Description |
Sig_block |
The new signal shielding word of the process is the set of its current signal mask and set pointing signal set. |
Sig_unblock |
The signal shielding word of the process is the intersection of the current signal mask and set point signal set replenishment. The set contains the signals we want to unblock. |
Sig_setmask |
The new signal screen word of the process is set to the set of signals that the set points to. |
Let's look at an example below. In the following program file, call Sigprocmask to set the blocking signal sigalrm, and then call Alarm (2) to set an alarm for two seconds (two seconds will produce a SIGALRM signal to the current process). After 4 seconds of sleep (this should have produced a SIGALRM signal), call the Sigprocmask function to unblock the signal sigalrm.
#include <stdlib.h>#include<stdio.h>#include<unistd.h>#include<string.h>#include<errno.h>#include<signal.h>Static voidSig_alrm (intSigno) {printf ("received sigalrm\n");}intMain (void) {sigset_t sigset; Sigemptyset (&sigset); Sigaddset (&Sigset, SIGALRM); if(Sigprocmask (Sig_block, &sigset, NULL) <0) {printf ("sigprocmask Error:%s\n", Strerror (errno)); Exit (-1); } if(Signal (SIGALRM, SIG_ALRM) <0) {printf ("signal Error:%s\n", Strerror (errno)); Exit (-1); } Alarm (2); Sleep (4); printf ("before unblock sigprocmask\n"); if(Sigprocmask (Sig_unblock, &sigset, NULL) <0) {printf ("sigprocmask sig_unblock Error:%s\n", Strerror (errno)); Exit (-1); } printf ("before exit\n"); Exit (0);}
sigprocmaskdemo.c
Compile the program file SIGPROCMASKDEMO.C, generate and execute the file Sigprocmaskdemo,
gcc -o sigprocmaskdemo sigprocmaskdemo.clienhua34:demo$. /Sigprocmaskdemobefore unblock sigprocmaskreceived sigalrmbefore exit
From the execution output above, we see that the signal sigalrm is passed to the current process for processing after calling the Sigprocmask function execution unblock. If we comment out Sigprocemask (Sig_block, &sigset, NULL) in sigprocmaskdemo.c, compile the execution, produce the following result,
lienhua34:demo$./sigprocmaskdemoreceived Sigalrmbefore unblock Sigprocmaskbefore exit
4 sigpending get process-pending signal set
The function sigpending gets all the pending signals of the current process. Returns the outstanding set of signals through its set parameters.
#include <signal.h>
int sigpending (sigset_t *set);
Return value: Returns 0 if successful, or 1 if an error occurs
Let's look at an example
#include <stdlib.h>#include<stdio.h>#include<unistd.h>#include<string.h>#include<errno.h>#include<signal.h>voidalrm_is_pending (Const Char*str) {sigset_t pendingsigset; printf ("%s:", str); if(Sigpending (&pendingsigset) <0) {printf ("sigpending Error:%s\n", Strerror (errno)); Exit (-1); } if(Sigismember (&Pendingsigset, SIGALRM)) {printf ("Sigalrm is pending\n"); } Else{printf ("sigalrm is not pending\n"); }}intMain (void) {sigset_t sigset; Sigemptyset (&sigset); Sigaddset (&Sigset, SIGALRM); if(Sigprocmask (Sig_block, &sigset, NULL) <0) {printf ("sigprocmask Error:%s\n", Strerror (errno)); Exit (-1); } alrm_is_pending ("before alarm"); Alarm (2); Sleep (4); Alrm_is_pending ("After alarm"); Exit (0);}
sigpendingdemo.c
Compile the program SIGPENDINGDEMO.C, generate and execute the file Sigpendingdemo. From the results below, we see that the call to the alarm function generates a signal SIGALRM, which is the signal set in the set parameter of the Sigpending function.
gcc -o sigpendingdemo sigpendingdemo.clienhua34:demo$. /Sigpendingdemobefore ALARM:SIGALRM isn't pendingafter alarm:sigalrm is pending
(done)
UNIX Environment Programming Learning Note (24)-signal set for advanced learning of signal processing and process signal shielding word