sigsuspend的整个原子操作过程为:(1) 设置新的mask阻塞当前进程;(2) 收到信号,恢复原先mask;(3) 调用该进程设置的信号处理函数;(4) 待信号处理函数返回后,sigsuspend返回。
/********************************************************************************************************************** * FILE NAME : tell_wait.cpp * CREATE DATE : 2011/06/25 * MODULE : view * AUTHOR : zengqh *---------------------------------------------------------------------------------------------------------------------* * MEMO : **********************************************************************************************************************/ #include <stdlib.h> #include <stdio.h> #include <unistd.h> #include "apue.h" #include <signal.h> #include <errno.h> /********************************************************************************************************************** * Macros and Structs **********************************************************************************************************************/ #define SUCCESS (0) #define FAILURE (-1) /********************************************************************************************************************** * Global Variables Definition Section **********************************************************************************************************************/ static volatile sig_atomic_t sig_flag = 0; static sigset_t newmask, oldmask, zeromask; /********************************************************************************************************************** * Functions **********************************************************************************************************************/ static void sig_usr(int signo) { sig_flag = 1; } int tell_wait() { if(SIG_ERR == signal(SIGUSR1, sig_usr)) { printf("signal failed: SIGUSR1./n"); return FAILURE; } if(SIG_ERR == signal(SIGUSR2, sig_usr)) { printf("signal failed: SIGUSR2./n"); return FAILURE; } sigemptyset(&zeromask); sigemptyset(&newmask); sigaddset(&newmask, SIGUSR1); sigaddset(&newmask, SIGUSR2); if(sigprocmask(SIG_BLOCK, &newmask, &oldmask) < 0) { printf("sigprocmask failed./n"); return FAILURE; } return SUCCESS; } int tell_parent(pid_t pid) { kill(pid, SIGUSR2); return SUCCESS; } int wait_parent() { while(0 == sig_flag) { sigsuspend(&zeromask); } if(sigprocmask(SIG_SETMASK, &oldmask, NULL) < 0) { printf("sigprocmask failed./n"); return FAILURE; } return SUCCESS; } int tell_child(pid_t pid) { kill(pid, SIGUSR1); return SUCCESS; } int wait_child() { while(0 == sig_flag) { sigsuspend(&zeromask); } if(sigprocmask(SIG_SETMASK, &oldmask, NULL) < 0) { printf("sigprocmask failed./n"); return FAILURE; } return SUCCESS; } int main() { pid_t child_pid; tell_wait(); if((child_pid = fork()) < 0) { printf("fork child failed./n"); return FAILURE; } if(0 == child_pid) { sleep(5); tell_parent(getppid()); } else if(child_pid > 0) { printf("begin to wait child./n"); wait_child(); printf("end to wait child./n"); } return 0; } /********************************************************************************************************************** * Class **********************************************************************************************************************/ /********************************************************************************************************************** * Class Members **********************************************************************************************************************/ /*****************************************************EOF*************************************************************/