linux 下实现sleep详解及简单实例
sleep:
普通版本
1、基本设计思路:
1>注册SIGALRM信号的处理函数;
2>调用alarm(nsecs)设定闹钟;
3>调"htmlcode">
#include<stdio.h> #include<signal.h> void handler(int signo) {} int mysleep(int timeout) { struct sigaction act,oact; act.sa_handler = handler; act.sa_flags = 0; sigemptyset(&act.sa_mask); sigaction(SIGALRM,&act,&oact); alarm(timeout); pause(); int ret = alarm(0); sigaction(SIGALRM,&oact,NULL); return ret; } int main() { while(1) { printf("using musleep!\n"); mysleep(3); } return 0; }
相关函数分析:
#include <unistd.h> int pause(void);
pause函数使调"htmlcode">
#include <signal.h> int sigaction(int signo, const struct sigaction *act, struct sigaction *oact);
sigaction函数可以读取和修改与指定信号相关联的处理动作。调"htmlcode">
int sigemptyset(sigset_t *set);
函数sigemptyset初始化set所指向的信号集,使其中所有信号的对应bit清零,表"htmlcode">
#include <signal.h>"color: #ff0000">sigsuspend函数与pause函数:都可以将程序挂起,但是sigsuspend函数可以实现对信号屏蔽字的解除与挂起。sigprocmask
调"htmlcode">
#include <signal.h>"//img.jbzj.com/file_images/article/201706/20176893511849.png" alt="" />
如果调"htmlcode">
#include<stdio.h> #include<signal.h> void handler(int signo) {} int mysleep(int timout) { struct sigaction act,oact; sigset_t newmask,oldmask,suspmask; act.sa_handler = handler; act.sa_flags = 0; sigemptyset(&act.sa_mask); sigaction(SIGALRM,&act,&oact); sigemptyset(&newmask); sigaddset(&newmask,SIGALRM); sigprocmask(SIG_BLOCK,&newmask,&oldmask); alarm(timout); suspmask = oldmask; sigdelset(&suspmask,SIGALRM); sigsuspend(&suspmask); int unslept = alarm(0); sigaction(SIGALRM,&oact,NULL); sigprocmask(SIG_SETMASK,&oldmask,NULL); return(unslept); } int main() { while(1) { printf("using musleep!\n"); mysleep(3); } return 0; }优化版本解决了普通版本存在的竞态问题。我们重新审视一下普通版本的时序问题。
1、设置SIGALRM信号的处理函数;
2、调用alarm()函数设置闹钟;
3、内核选取更高优先级的进程来取代当前进程,并且这样的进程很多,同时执行时间又很长;
4、闹钟超时了,内核发送SIGALRM信号给该进程,并且处于未决状态;
5、优先级更高的进程结束后,内核要调度回这个进程执⾏。 SIGALRM信号递达,执⾏处理函 数sig_alrm之后再次进⼊内核。
6、返回这个进程的主控制流程,alarm(nsecs)返回,调⽤pause()挂起等待。
7、可是现在SIGALRM信号已经被处理,进程会导致错误。
在一个进程运行过程中,因为由于异步,所以可能被其他优先级更高的进程,由于时序问题而引发的错误问题。这样的问题称为竞态问题。
优化版本中,先将设置SIGALRM信号的处理函数,然后将SIGALRM信号进行屏蔽,然后调用alarm()函数设置闹钟,然后调用sigprocmask()函数对SIGALRM信号解除屏蔽然后挂起等待,这样就解决了竞态问题。
感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!
免责声明:本站文章均来自网站采集或用户投稿,网站不提供任何软件下载或自行开发的软件! 如有用户或公司发现本站内容信息存在侵权行为,请邮件告知! 858582#qq.com
P70系列延期,华为新旗舰将在下月发布
3月20日消息,近期博主@数码闲聊站 透露,原定三月份发布的华为新旗舰P70系列延期发布,预计4月份上市。
而博主@定焦数码 爆料,华为的P70系列在定位上已经超过了Mate60,成为了重要的旗舰系列之一。它肩负着重返影像领域顶尖的使命。那么这次P70会带来哪些令人惊艳的创新呢?
根据目前爆料的消息来看,华为P70系列将推出三个版本,其中P70和P70 Pro采用了三角形的摄像头模组设计,而P70 Art则采用了与上一代P60 Art相似的不规则形状设计。这样的外观是否好看见仁见智,但辨识度绝对拉满。