先来说说工作原理,linux中的sleep函数能够让程序休眠一定的秒数,到时间后自动恢复运行。
实现思路
设定睡眠的秒数
睡眠(挂起)
恢复运行
实现机制
设定睡眠的秒数:采用alarm()函数设定需要睡眠的秒数,到时间后闹钟会发送SIGALRM信号给当前进程。但SIGALRM信号的默认操作是杀死进程,所以我们需要对SIGALRM信号进行自定义处理。
睡眠:pause()函数会让当前进程挂起,直到收到信号才会出错返回。
示例程序代码:模拟实现sleep使当前进程每2秒打印”hello yingying\n”
#include<stdio.h> #include<unistd.h> #include<signal.h> void handler(int signo)//由于程序在睡眠期间什么也不做所以自定义处理函数不执行任何操作 { } int mysleep(int time) { sigset_t set; sigemptyset(&set); struct sigaction act; struct sigaction oact; act.sa_handler = handler;//自定义处理函数 act.sa_mask = set; act.sa_flags = 0; sigaction(SIGALRM,&act,&oact);//捕捉闹钟信号自定义处理动作 alarm(time);//time秒后给进程发送信号 pause();//挂起进程 int _time = alarm(0);//如果程序被提前唤醒取消闹钟 sigaction(SIGALRM,&oact,NULL);//恢复捕捉信号的原始状态 return _time; } int main() { while(1) { printf("hello yingying\n"); mysleep(2); } return 0; }
问题分析
上述代码在看似没有问题可以实现我们需要的结果,但是带 多执行流下仍可以正常运行吗?例如在设定了闹钟后当前进程被切换出去,等再切换回来闹钟已经响过了,那么当前进程就会被永远挂起。所以我们需要优化上面的程序。
.优化方案一:
1.屏蔽SIGALRM信号
2.alarm(time)
3.解除屏蔽SIGALRM信号
4.pause()
.优化方案二:
1.屏蔽SIGALRM信号
2.alarm(time)
3.pause()
4.解除屏蔽SIGALRM信号
这两种方案大家思考一下可行吗?应该选哪个呢?
方案选择
对于方案一:如果进程在解除屏蔽之后,pause()之前的的间隙被切走仍会造成同样的问题,进程也可能被永远挂起。
对于方案二:程序挂起之后,闹钟信号被屏蔽,一直处于未决状态,程序无法收到信号,进程也就会被一直挂起。所以方案二是不可以选择的。
对于方案一我们可以改进,使解除阻塞与挂起成为一个原子操作这样就可以解决我们的问题了。
解决问题
像方案一这种由时序问题导致程序出现问题的情况成为竞态条件。sigsuspend()函数可以实现pause()函数的挂起功能,同时也能解决竞态条件的问题。sigsuspend()函数的功能就是-“解除信号屏蔽”-“挂起进程等待信号”-“执行信号处理函数”- “出错返回”。所以sigsuspend()函数函数同pause()函数一样只有出错返回值。在对程序时序要求比较严格的程序中一般使用sigsuspend()函数。
优化后的程序代码
#include<stdio.h> #include<unistd.h> #include<signal.h> void handler(int signo) { } int mysleep(int time) { sigset_t set,oset,susmask; sigemptyset(&set); sigaddset(&set,SIGALRM); sigprocmask(SIG_BLOCK,&set,&oset); struct sigaction act; struct sigaction oact; act.sa_handler = handler; act.sa_mask = set; act.sa_flags = 0; sigaction(SIGALRM,&act,&oact); alarm(time); susmask = oset; sigdelset(&susmask,SIGALRM); sigsuspend(&susmask); int _time = alarm(0); sigaction(SIGALRM,&oact,NULL); sigprocmask(SIG_BLOCK,&oset,NULL); return _time; } int main() { while(1) { printf("hello yingying\n"); mysleep(2); } return 0; }
这样我们的sleep函数的模拟实现就完成了。
程序结果
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
Linux,sleep,函数
免责声明:本站文章均来自网站采集或用户投稿,网站不提供任何软件下载或自行开发的软件! 如有用户或公司发现本站内容信息存在侵权行为,请邮件告知! 858582#qq.com
RTX 5090要首发 性能要翻倍!三星展示GDDR7显存
三星在GTC上展示了专为下一代游戏GPU设计的GDDR7内存。
首次推出的GDDR7内存模块密度为16GB,每个模块容量为2GB。其速度预设为32 Gbps(PAM3),但也可以降至28 Gbps,以提高产量和初始阶段的整体性能和成本效益。
据三星表示,GDDR7内存的能效将提高20%,同时工作电压仅为1.1V,低于标准的1.2V。通过采用更新的封装材料和优化的电路设计,使得在高速运行时的发热量降低,GDDR7的热阻比GDDR6降低了70%。
更新日志
- 群星《前途海量 电影原声专辑》[FLAC/分轨][227.78MB]
- 张信哲.1992-知道新曲与精丫巨石】【WAV+CUE】
- 王翠玲.1995-ANGEL【新艺宝】【WAV+CUE】
- 景冈山.1996-我的眼里只有你【大地唱片】【WAV+CUE】
- 群星《八戒 电影原声带》[320K/MP3][188.97MB]
- 群星《我的阿勒泰 影视原声带》[320K/MP3][139.47MB]
- 纪钧瀚《胎教古典音乐 钢琴与大提琴的沉浸时光》[320K/MP3][148.91MB]
- 刘雅丽.2001-丽花皇后·EMI精选王【EMI百代】【FLAC分轨】
- 齐秦.1994-黄金十年1981-1990CHINA.TOUR.LIVE精丫上华】【WAV+CUE】
- 群星.2008-本色·百代音乐人创作专辑【EMI百代】【WAV+CUE】
- 群星.2001-同步过冬AVCD【环球】【WAV+CUE】
- 群星.2020-同步过冬2020冀待晴空【环球】【WAV+CUE】
- 沈雁.1986-四季(2012梦田复刻版)【白云唱片】【WAV+CUE】
- 纪钧瀚《胎教古典音乐 钢琴与大提琴的沉浸时光》[FLAC/分轨][257.88MB]
- 《国语老歌 怀旧篇 3CD》[WAV/分轨][1.6GB]