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. The flowchart from the signal generation to the target process is as follows:
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.
Signal set:
The function Sigemptyset initializes the set of signals that the set points to, clearing all of the signals.
1 int sigemptyset (sigset_t *set);
return value : returns 0 if successful , or 1 function sigfillset initialized by set If an error occurs point to the signal set so that it contains all the signals.
2 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.
3 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.
4 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 .
5 int Sigismember (const sigset_t *set, int signo);
return value : returns 1 if true , returns 0 if false , or 1 If an error occurs
function Sigprocmask
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 the following table:
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 take a look at the specific usage examples
void sig_alarm (int signo) {
printf ("Received sigalrm\n");
Return
}
void Signal_set_fun () {
sigset_t Sigset;
Sigemptyset (&sigset);
Sigaddset (&SIGSET,SIGALRM);
if (Sigprocmask (sig_block,&sigset,null) <0) {
printf ("Sigprocmask error:\n");
}
if (signal (Sigalrm,sig_alarm) < 0) {
printf ("Signal error:\n");
}
Alarm (2);
Sleep (4);
printf ("Before unblock sigprocmask\n");
if (Sigprocmask (sig_unblock,&sigset,null) <0) {
printf ("Sigprocmask unblock error:\n");
}
}
In the program file above, 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.
The results of the operation are as follows:
function sigpending
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
Take a look at an example of practical use:
void Alarm_is_pending (char *str) {
sigset_t Pendingsig;
printf ("%s:\n", str);
if (sigpending (&pendingsig) < 0) {
printf ("Sigpending required error:\n");
}
if (Sigismember (&PENDINGSIG,SIGALRM)) {
printf ("Sigalrm is pending\n");
}
else{
printf ("Sigalrm is not pending\n");
}
}
void Signal_pending_fun () {
sigset_t Sigset;
Sigemptyset (&sigset);
Sigaddset (&SIGSET,SIGALRM);
if (Sigprocmask (Sig_block,&sigset,null) < 0) {
printf ("Sigprocmask error:\n");
}
Alarm_is_pending ("before alarm");
Alarm (2);
Sleep (4);
Alarm_is_pending ("after Alarm");
Exit (0);
}
Operation Result:
Linux C Programming: Signal (iii) Sigprocmask and sigpending functions