一、
#include<stdio.h>
#include<signal.h>
#include<unistd.h>
void myhandler(int sig) //句柄函数什么也不做
{}
int mysleep(int timeout)
{
struct sigaction act,oact;
act.sa_handler = myhandler;
sigemptyset(&act.sa_mask);//信号集的初始化
act.sa_flags = 0;
sigaction(SIGALRM,&act,&oact);//注册信号处理函数
alarm(timeout);//设置闹钟
pause();//将自己挂起直到有信号递达
int ret = alarm(0);//取消闹钟
sigaction(SIGALRM,&oact,NULL);//恢复对SIGALRM信号的处理动作
return ret;
}
int main()
{
while(1)
{
mysleep(2);
printf("use mysleep!\n");
}
return 0;
}
二、避免竞态条件的mysleep
#include<stdio.h>
#include<signal.h>
void myhandler(int sig)
{
//printf("get a sig:%d\n",sig);
}
struct sigaction act,oact;
sigset_t newmask,oldmask,suspmask;//设置信号集
act.sa_handler = myhandler;
sigemptyset(&act.sa_mask);//信号集的初始化
act.sa_flags = 0;
sigaction(SIGALRM,&act,&oact);//读取和修改与SIGALRM信号相关联的处理动作
sigemptyset(&newmask);//初始化信号集
sigaddset(&newmask,SIGALRM);//为信号集添加SIGALRM信号
alarm(timeout);//设置闹钟
sigdelset(&oldmask,SIGALRM);//从信号集oldmask中删除SIGALRM信号
sigsuspend(&oldmask);//将当前进程的信号屏蔽字设为oldmask,在进程接受到信号之前,进程会挂起,当捕捉一个信号,首先执行信号处理程序,然后从sigsuspend返回,最后将信号屏蔽字恢复为调用sigsuspend之前的值
//pause();//将自己挂起直到有信号递达
int ret = alarm(0);//取消闹钟
sigaction(SIGALRM,&oact,NULL);//恢复对SIGALRM信号的处理动作
return ret;
}
int main()
{
while(1)
{
mysleep(2);
printf("use mysleep!\n");
}
return 0;
}
三、对比两种方法: