Sigsuspend is an atomic operation that exists to prevent signal loss. For more information, see the function prototype.
Int sigsuspend (const sigset_t * mask );
Ignore the parameter first. The operation completed by sigsuspend is to block the running of the process until a signal is generated. In this way, it serves the same purpose as another function. Pause ()
According to the parameters, the operation completed by sigsuspend is the operation of the blocking process. If the signal is the signal set by the mask parameter, the signal is in pending state without affecting the blocking status of the process, it means that the process is still blocked until the signal that is not in the signal set appears, and the process can continue to run. Note: If a signal exists in the mask signal set, the signal will be captured by the process after the sigsuspend function returns, and the custom or default signal response function will be completed.
Experiment: sigsuspend blocks the SIGINT signal. During blocking, The SIGINT signal is sent before the SIGUSR1 signal is sent.
#include <unistd.h>#include <stdlib.h>#include <stdio.h>#include <signal.h>static int proc_sig=0;sigset_t zeromask;void pr_mask(const char* str);void proc_usr1(int){ printf("proc_usr1\n"); pr_mask("In sigusr1:");};int main(){ sigset_t sigset, oldmask, waitmask; signal(SIGUSR1, proc_usr1); sigprocmask(0, NULL, &oldmask); //sigaddset(&sigset, SIGUSR1); //sigprocmask(SIG_BLOCK, &sigset, NULL); //pr_mask("Block SIGUSR1"); pr_mask("Before suspend"); sigaddset(&waitmask, SIGINT); sigsuspend(&waitmask); pr_mask("After suspend:"); //sleep(12); //sigprocmask(SIG_UNBLOCK, &sigset, NULL); //pr_mask("Unblock SIGUSR1"); sleep(12); return 0;}void pr_mask(const char * str){ sigset_t sigset; sigprocmask(0, NULL, &sigset); printf("%s:", str); if (sigismember(&sigset, SIGCHLD)) printf("SIGCHLD "); if (sigismember(&sigset, SIGALRM)) printf("SIGALRM "); if (sigismember(&sigset, SIGUSR2)) printf("SIGUSR2 "); if (sigismember(&sigset, SIGUSR1)) printf("SIGUSR1 "); if (sigismember(&sigset, SIGSTOP)) printf("SIGSTOP "); if (sigismember(&sigset, SIGKILL)) printf("SIGKILL ");
if (sigismember(&sigset, SIGINT)) printf("SIGINT "); printf("\n");}
Run: Ctrl + C (send SIGINT signal) first, then send signal SIGUSR1 (kill-SIGUSR1 PID)
Output:
Before suspend:^Cproc_usr1In sigusr1::SIGUSR1 SIGINT
Output explanation: the first line of output indicates that the process has not set signal shielding characters.
The second line shows the CTRL + C signal, followed by the output of the signal response function proc_usr1
The third line is the output of proc_usr1. The blocked characters of the current process include SIGINT (set by sigsuspend) and SIGUSR1 (SIGUSR1 will also appear in the current blocked word if you do not understand it)
For the above question: why does SIGUSR1 also appear in the currently blocked word?
Assume that the current process receives the SIGUSR1 signal and enters the proc_usr1 signal processing function. During the function execution, it receives another SIGUSR1 signal. What will the process do?
The OS should first accept the signal. After the response function of SIGUSR1 is complete, the OS throws the signal to the current process and the current process continues to respond to the SIGUSR1.
This explains why the SIGUSR1 signal is blocked. In the response function of a signal, the signal must be set to blocked, that is, the current process does not respond to this signal within the response function processing time.