mysleep
Posted Luella_G
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了mysleep相关的知识,希望对你有一定的参考价值。
一、普通版本的mysleep函数
1.main函数调用mysleep函数,后者调用sigaction注册了SIGALRM信号的处理函数handler。
2.调用alarm(timeout)设定闹钟。
3.调用pause等待,内核切换到别的进程运行。
4.timeout秒之后,闹钟超时,内核发SIGALRM给这个进程。
5.从内核态返回这个进程的用户态之前处理未决信号,发现有SIGALRM信号,其处理函数是handler。
6.切换到用户态执行handler函数,进入handler函数时SIGALRM信号被自动屏蔽, 从handler函数返回时SIGALRM信号自动解除屏蔽。然后自动执行系统调用sigreturn再次进入 内核,再返回用户态继续执行进程的主控制流程(main函数调用的mysleep函数)。
7.pause函数返回-1,然后调用alarm(0)取消闹钟,调用sigaction恢复SIGALRM信号以前的处理动作。
代码实现:
#include<stdio.h>
#include<signal.h>
#include<unistd.h>
#include<stdlib.h>
void handler(int signum)
int mysleep(int time)
struct sigaction act,oldact;
act.sa_handler = handler;
int sa_flags = 0;
sigset_t sa_mask;
sigemptyset(&sa_mask);
sigaction(SIGALRM, &act, &oldact);
alarm(time);
pause();
int ret = alarm(0);
sigaction(SIGALRM, &act, NULL);
return ret;
int main()
while(1)
mysleep(1);
printf("I am sleeping!!\\n");
return 0;
运行结果:
二、规避竞态条件的mysleep函数
1.屏蔽SIGALRM信号;
2.alarm(time);
3.解除对SIGALRM的屏蔽;
4.pause();
代码实现:
#include<stdio.h>
#include<signal.h>
#include<unistd.h>
#include<stdlib.h>
void handler(int signum)
int mysleep(int time)
struct sigaction act,oldact;
act.sa_handler = handler;
int sa_flags = 0;
sigset_t sa_mask, oldmask, suspmask;
sigaction(SIGALRM, &act, &oldact);
sigemptyset(&sa_mask);
sigaddset(&sa_mask, SIGALRM);
sigprocmask(SIG_BLOCK, &sa_mask, &oldmask);
alarm(time);
suspmask = oldmask;
sigdelset(&suspmask, SIGALRM);
sigsuspend(&suspmask);
int ret = alarm(0);
sigaction(SIGALRM, &act, NULL);
sigprocmask(SIG_SETMASK, &oldmask, NULL);
return ret;
int main()
while(1)
mysleep(1);
printf("I am sleeping!!\\n");
return 0;
运行结果:
以上是关于mysleep的主要内容,如果未能解决你的问题,请参考以下文章