In that year, I learned Linux C-sigsuspend Execution Process Analysis step by step.

Source: Internet
Author: User

This series of articles written by muge0913, reproduced please note the Source: http://blog.csdn.net/muge0913/article/details/7334840


Used to temporarily replace the signal mask of a process with a mask before receiving a signal, and pause the process until the signal is received.

  /*The sigsuspend() function replaces the current signal mask of the calling thread with the set of signals pointed      to by sigmask and then suspends the thread until delivery of a signal whose action is either to execute a signal-catching     function or to terminate the process. This will not cause any other signals that may have been pending on the process to     become pending on the thread.  If the action is to terminate the process then sigsuspend() will never return. If the action is to execute a signal-catching     function, thensigsuspend() will return after the signal-catching function returns, with the signal mask restored to the set     that existed prior to thesigsuspend() call.  It is not possible to block signals that cannot be ignored. This is enforced by the system without causing an error to be indicated.*/

That is to say, after sigsuspend, the process will be there, waiting for the open signal to wake up. After receiving the signal, the system immediately restores the current signal set to the original one, and then calls the processing function.

In the book "Advanced Programming for UNIX environments", the Steven s replied, "If a signal is caught and if the signal handler returns, then sigsuspend returns and the signal mask of the process is set to its value before
The call to sigsuspend. "Because sigsuspend is an atomic operation, this sentence gives us the feeling that we call signal handler to return the result first, and then sigsuspend to return the result.

int main(void) {   sigset_t   newmask, oldmask, zeromask;   if (signal(SIGINT, sig_int) == SIG_ERR)      err_sys("signal(SIGINT) error");   sigemptyset(&zeromask);   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 */   pr_mask("in critical region: ");   /* allow all signals and pause */   if (sigsuspend(&zeromask) != -1)      err_sys("sigsuspend error");   pr_mask("after return from sigsuspend: ");   /* reset signal mask which unblocks SIGINT */   if (sigprocmask(SIG_SETMASK, &oldmask, NULL) < 0)      err_sys("SIG_SETMASK error");   /* and continue processing ... */   exit(0);}static void sig_int(int signo) {   pr_mask("\nin sig_int: ");   return;}

 
Result:

$a.outin critical region: SIGINT^Cin sig_int: SIGINTafter return from sigsuspend: SIGINT

If the return is based on sig_handler, The SIGINT should not be printed, because at that time the blocked word has not been restored, and all signals are not blocked. So is it Steven s wrong? Of course not. But what did Steven do in sigsuspend's atomic operation?
The entire atomic operation process of sigsuspend is:
(1) set a new mask to block the current process;
(2) receive the signal and restore the original mask;
(3) Call the signal processing function set by this process;
(4) After the signal processing function returns, sigsuspend returns.
This process is basically the process above. Oh, the original signal handler is part of the atomic operation and is executed after the blocked word is restored. Therefore, the above example is correct, that's right for Steven. Because Linux and UNIX are closely related, the semantics of most system calls on the two platforms are consistent. The above sigsuspend atomic operations were also obtained from the book "deep understanding of Linux kernel. The description is as follows:

/*The sigsuspend( ) system call puts the process in the TASK_INTERRUPTIBLE state, after having blocked the standard signals specified by a bit mask array to which the mask parameter points. The process will wake up only when a nonignored, nonblocked signal is sent  to it. The corresponding sys_sigsuspend( ) service routine executes these statements:*/mask &= ~(sigmask(SIGKILL) | sigmask(SIGSTOP));spin_lock_irq(¤t->sigmask_lock);saveset = current->blocked;siginitset(¤t->blocked, mask);recalc_sigpending(current);spin_unlock_irq(¤t->sigmask_lock);regs->eax = -EINTR;while (1) {    current->state = TASK_INTERRUPTIBLE;    schedule(  );    if (do_signal(regs, &saveset))        return -EINTR;} 

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.