Linux环境下模拟实现sleep函数
来源:互联网 发布:java面试葵花宝典 pdf 编辑:程序博客网 时间:2024/05/17 16:56
Linux环境下模拟实现sleep函数
1.代1
1.代码中用到的库函数、结构体介绍
SIGALRM 信号: 时钟定时信号, 计算的是实际的时间或时钟时间, alarm函数使用该信号。alarm函数:#include <unistd.h>
unsigned int alarm(unsigned int seconds);
- 1
- 2
#include <unistd.h>
int pause(void);
pause函数使调用进程挂起直到有信号递达。pause只有出错的返回值。errno设置为EINTR表示“被信号中断”。 如果信号的处理动作是终止进程,则进程终止, pause函数没有机会返回; 如果信号的处理动作是忽略,则进程继续处于挂起状态, pause不返回; 如果信号的处理动作是捕捉,则调用了信号处理函数之后pause返回- 1;sigaction函数:#include <signal.h>
int sigaction(int signo, const struct sigaction *act, structsigaction *oact);
2.普通版本的mysleep函数
#include#include #include void handler(int sig) {} 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 mysleep \n"); mysleep(3); } } 程序运行结果:部分函数解释:调用alarm(timeout)设定闹钟。 调用pause等待,内核切换到别的进程运行。 timeout秒之后,闹钟超时,内核发SIGALRM给这个进程。
3.避免竞态条件的mysleep
由于时序问题而导致的错误,叫做竞态条件在普通版本的mysleep程序中,我们设想的时序是1.注册SIGALRM信号的处理函数2.调用alarm(n)设定闹钟3,内核调度优先级更高的进程取代当前进程执行,并且优先级更高的进程有很多个,每个都要执行很长时间4.n秒钟之后闹钟超时了,内核发送SIGALRM信号给这个进程,处于未决状态5.优先级更高的进程执行完,内核要调度回这个进程继续执行。SIGALRM信号递达,执行处理函数后再次进入内核6.返回这个进程的主控制流程,alarm(n)返回,调用pause()挂起等待
由于系统运行代码时并不会按照我们的思路走,虽然alarm(timeout)紧接着的下一行就是pause(),但是无法保证pause()一定
会在调用alarm(timeout)之后的timeout秒之内被调用。
由于异步事件在任何时候都有可能发生,如果写程序时考虑不周密,就可能由于时序问题而导致错误。
只有将“解除信号屏蔽”和“挂起等待信号”两步合并成一个原子操作,才能避免由于竞态条件带来的错误。
sigsuspend函数正好可以完成这个功能。sigsuspend包含了pause的挂起等待功能,同时解决了竞态条件的问题
#include#include #include void handler(int sig) {} int mysleep(int timeout) { struct sigaction act,oact; sigset_t mask,omask,suspmask; unsigned int unslept; act.sa_handler=handler; act.sa_flags=0; sigemptyset(&act.sa_mask); sigaction(SIGALRM,&act,&oact); sigemptyset(&mask); sigaddset(&mask,SIGALRM); sigprocmask(SIG_BLOCK,&mask,&omask); alarm(timeout); suspmask=omask; sigdelset(&suspmask,SIGALRM); sigsuspend(&suspmask); int ret=alarm(0); sigaction(SIGALRM,&oact,NULL); sigprocmask(SIG_SETMASK,&omask,NULL); return ret; } int main() { while(1) { printf("using mysleep \n"); mysleep(3); } } 1,5 Top
sigsuspend函数是pause函数的增强版。当sigsuspend函数的参数信号集为空信号集时,sigsuspend函数是和pause函数是一样的,可以
接受任何信号的中断。 但,sigsuspend函数可以屏蔽信号,接受指定的信号中断。 sigsuspend函数=pause函数+指定屏蔽信号
阅读全文
0 0
- Linux环境下模拟实现sleep函数
- 在Linux环境下模拟实现sleep函数
- LINUX下模拟实现sleep函数
- 【Linux】模拟实现sleep函数
- 【Linux】模拟实现sleep函数
- 【linux】:模拟实现sleep函数
- Linux中模拟实现sleep函数
- 模拟实现sleep函数
- 模拟实现sleep函数
- Linux模拟实现sleep
- Linux下,实现一个sleep函数
- javascript模拟实现sleep函数
- Linux 信号 模拟实现sleep
- LINUX下实现sleep
- linux下模拟实现sleep以及sleep会出现的问题解决方案
- linux下使用sleep()函数
- linux下c++sleep函数
- 模拟实现sleep函数——mysleep()
- 存储过程与函数的区别
- input框的回车事件
- 内部排序算法:直接选择排序法
- 微服务框架Spring Cloud介绍 Part1: 使用事件和消息队列实现分布式事务
- java melody 如何整合nutzframework监控action方法?
- Linux环境下模拟实现sleep函数
- Bootstrap Paginator使用
- android中shape的使用
- 【python 淘宝爬虫】淘宝信誉分抓取
- File.separator 实现Windows和Linux文件路径中的斜线
- 直播营销系统搭建在公众号上有什么好处?
- gh0st远控源码图文详解Gh0st通信协议解析(1)
- Ubuntu下Android Studio环境搭建
- 安卓sqlite数据库简单的增删改查和数据库版本更新