Linux C Programming: Signal (v) sigsuspend

Source: Internet
Author: User
Tags signal handler

Changing the signal screen word of a process can block the selected signal or unblock them. Use this technique to protect code critical sections that you do not want to be interrupted by a signal. What if you want to unblock a signal and then pause to wait for a previously blocked signal to occur? An incorrect way to achieve this is to assume that the signal is SIGINT:

sigset_t Newmask, Oldmask;

Sigemptyset (&newmask);

Sigaddset (&newmask, SIGINT);

/* Block SIGINT and save current signal mask */if (Sigprocmask (Sig_block, &newmask, &oldmask) < 0)

Err_sys ("Sig_block error");

/* Critical Region of code */if (Sigprocmask (Sig_setmask, &oldmask, NULL) < 0)

Err_sys ("Sig_setmask error");

/* window is open */

Pause (); /* Wait for signal to occur */

/* Continue processing */

If it is sent to the process when the signal is blocked, the signal's delivery is deferred until it is unblocked. For the application, the signal appears to be between the unblocking of the SIGINT and the pause . If this happens, or if a signal does occur between the time of unblocking and pause , then a problem arises. Since we may not see the signal again, in this sense, The signal that occurs in this time window (between unblocking and pause) is lost so that pause is blocked forever.

To correct this problem, you need to first restore the signal mask word in an atomic operation and then hibernate the process. This functionality is provided by the sigsuspend function.

#include <signal.h>

int sigsuspend (const sigset_t *sigmask);

return value:-1, and set errno to Eintr

Sets the signal screen character of the process to The value pointed to by Sigmask. The process is suspended until a signal is captured or a signal is signaled to terminate the process. If a signal is captured and returned from the signal handler, sigsuspend returns and sets the signal screen word of the process to the value before the call to sigsuspend .

#include <unistd.h>

#include <signal.h>

#include <stdio.h>

void handler (int sig)// Signal Processing program

{

if (sig = = SIGINT)

printf ("SIGINT sig");

else if (sig = = Sigquit)

printf ("Sigquit sig");

Else

printf ("SIGUSR1 sig");

}

int main ()

{

sigset_t new,old,wait; three set of signals

struct Sigaction Act;

Act.sa_handler = handler;

Sigemptyset (&act.sa_mask);

act.sa_flags = 0;

Sigaction (SIGINT, &act, 0); The following three signals can be captured:sigint/sigquit/sigusr1

Sigaction (sigquit, &act, 0);

Sigaction (SIGUSR1, &act, 0);

Sigemptyset (&new);

Sigaddset (&new, SIGINT); SIGINT Signal added to the new signal set

Sigemptyset (&wait);

Sigaddset (&wait, SIGUSR1); SIGUSR1 signal Join wait

Sigprocmask (Sig_block, &new, &old); block SIGINT , save current signal set to old

critical section Code execution

if (Sigsuspend (&wait)! =-1)//program hangs here; replace the new signal set with the wait signal set . That is: Come over SIGUSR1 letter , block out, the program continues to hang; other signals, such as SIGINT, Wake the program. Performs Atomic operations on Sigsuspend. Note: If "Sigaddset (&wait, SIGUSR1);" This does not block any signal here, that is, any signal will wake up the program.

printf ("Sigsuspend error");

printf ("After Sigsuspend");

Sigprocmask (Sig_setmask, &old, NULL);

return 0;

}

the atomic operation of the Sigsuspend is:

(1 Span style= "Font-family:times New Roman" >mask blocking current process ( wait replace new SIGUSR1 signal )

(2 SIGUSR1 signal, block, program continues to hang, receive other signals, restore original mask ( sigint signal "

(3 ( If you first come to SIGUSR1 signal, then come over sigint signal, the signal processing function will be called two times to print different content. First print sigint, second print SIGUSR1 SIGUSR1 front blocked "

(4) when the signal processing function returns,sigsuspend returns. (sigsuspend integrates the capture signal and signal processing functions together )

Linux C Programming: Signal (v) sigsuspend

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.