/*
author: youfl
func :基于信号的阻塞式休眠
contact:393639665@qq.com
*/
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
void sig_alrm(int signo){
printf("handler signal no : %d\n", signo);
}
unsigned int mysleep(unsigned int nsecs){
sigset_t newmask,oldmask,susmask;
struct sigaction newaction,oldaction;
newaction.sa_handler = sig_alrm;
/*此处为不添加额外的阻塞信号,sigaction()执行类似于sigprocmask调用SIG_BLOCK
是将进程的当前屏蔽与newaction.sa_mask取并集作为进程新的信号屏蔽字
*/
sigemptyset(&newaction.sa_mask);
newaction.sa_flags = 0;
/*修改SIGALRM的处理方式*/
sigaction(SIGALRM,&newaction,&oldaction);
/*block SIGALRM*/
sigemptyset(&newmask);
sigaddset(&newmask, SIGALRM);
sigprocmask(SIG_BLOCK, &newmask, &oldmask);
alarm(nsecs);
/*
sigsuspend will reset the process mask,so 'susmask = oldmask'
get the original sigset, make sure sigsuspend not
change the original signals' block type;
sigsuspend() :
1.set the process mask = susmask, save the original mask
2.wait for the signal arrive
3.restore the proceess mask = original mask
*/
susmask = oldmask;
sigdelset(&susmask, SIGALRM);
sigsuspend(&susmask);
unsigned int unslept = alarm(0);
//resore the process mask
sigprocmask(SIG_SETMASK, &oldmask, NULL);
return unslept;
}
int main(){
while(1){
mysleep(2);
printf("Two seconds passed\n");
}
return 0;
}