Linux中模拟实现sleep函数
来源:互联网 发布:贵州大数据发展报告 编辑:程序博客网 时间:2024/05/19 00:48
sleep函数原理:当前进程挂起指定时间后继续运行
1、进程挂起
pause():进程挂起,直到收到一个信号,只有出错返回。
2、计时机制()
alarm():设定⼀一个闹钟,也就是告诉内核在seconds秒之后给当前进程发
SIGALRM信号, 该信号的默认处理动作是终⽌止当前进程。这个函数的返回值是0或者是以前设定的闹钟时间还余下 的秒数.
具体实现代码如下:
#include<stdio.h>#include<unistd.h>#include<signal.h>void handler(int signo){}int mysleep(int time){ struct sigaction act,oact; act.sa_handler = handler; sigemptyset(&act.sa_mask); act.sa_flags = 0; int ret = 0; sigaction(SIGALRM,&act,&oact); alarm(time); pause(); ret = alarm(0); sigaction(SIGALRM,&oact,NULL); return ret;}int main(){ while(1) { mysleep(1); printf("I am awake....!\n"); }}
但是在这个函数中,进程执行过程中,设定玩闹钟后,进程被切换了,当进程再次被切换回来时,闹钟时间有可能已经过了,这样pause()再也接收不到SIGALRM 信号,进程将永远挂起,我们可以这样做,在调用pause之前屏蔽SIGALRM信号使它不能提前递达就可以了有如下解决办法:
1. 屏蔽SIGALRM信号;
2. alarm(nsecs);
3. 解除对SIGALRM信号的屏蔽;
4. pause();
从解除信号屏蔽到调⽤用pause之间存在间隙,SIGALRM仍有可能在这个间隙递达。要消除这个间隙, 我们把解除屏蔽移到pause后⾯:
1. 屏蔽SIGALRM信号;
2. alarm(nsecs);
3. pause();
4. 解除对SIGALRM信号的屏蔽;
这样更不行了,还没有解除屏蔽就调⽤pause,pause根本不可能等到SIGALRM信号。要是“解除信号屏蔽”和“挂起等待信号”这两步能合并成⼀个原⼦子操作就好了。
sigsuspend函数就具有这样的功能:
int sigsuspend(const sigset_t *sigmask);
调用sigsuspend时,进程的信号屏蔽字由sigmask参数指定,可以通过指定sigmask来临时解除 对某 个信号的屏蔽,然后挂起等待,当sigsuspend返回时,进程的信号屏蔽字恢复为原来的值,如果原来对该信号是屏蔽的,从sigsuspend返回后仍然是屏蔽的。
下面用sigsuspend函数重新实现sleep函数:
#include<stdio.h>#include<unistd.h>#include<signal.h>void handler(int signo){}int mysleep(int time){ struct sigaction act,oact; sigset_t mask,omask,susmask; act.sa_handler = handler; sigemptyset(&act.sa_mask); act.sa_flags = 0; int ret; sigaction(SIGALRM,&act,&oact); sigemptyset(&mask); sigaddset(&mask,SIGALRM); sigprocmask(SIG_BLOCK,&mask,&omask); alarm(time); susmask = omask; sigdelset(&susmask,SIGALRM); sigsuspend(&susmask); ret = alarm(0); sigaction(SIGALRM,&oact,NULL); sigprocmask(SIG_SETMASK,&omask,NULL); return ret;}int main(){ while(1) { mysleep(1); printf("I am awake....!\n"); }}
- Linux中模拟实现sleep函数
- 【Linux】模拟实现sleep函数
- 【Linux】模拟实现sleep函数
- 【linux】:模拟实现sleep函数
- Linux环境下模拟实现sleep函数
- LINUX下模拟实现sleep函数
- 模拟实现sleep函数
- 模拟实现sleep函数
- Linux模拟实现sleep
- javascript模拟实现sleep函数
- 在Linux环境下模拟实现sleep函数
- Linux 信号 模拟实现sleep
- 模拟实现sleep函数——mysleep()
- Linux信号——Sleep函数的模拟实现(利用alarm,pause,sigsuspend函数)
- linux中sleep函数使用
- 模拟实现sleep方法
- 【Linux】利用信号实现sleep函数
- Linux下,实现一个sleep函数
- Xilinx ISE Design Suite 仿真使用图文教程
- sublime text3不识别项目目录的中文名字和调整侧边栏字体大小
- Hive的metastore三种模式配置介绍
- SQLSERVER DBCC命令大全
- [iOS ruby升级=>才能安装cocoaPods]使用rvm升级Ruby
- Linux中模拟实现sleep函数
- spring-boot 添加跨域支持
- SPRING源码学习之路(三)——<aop:config>自动代理的实现
- ARM开发板挂载Ubuntu主机的NFS共享文件夹
- Unity3D使用RenderCommand渲染外轮廓
- 美团校招 拜访
- Xshell连接不上虚拟机提示ssh服务器拒绝了密码,请再试一次
- Ubuntu 16.04中 Django + apache + wsgi 配置
- IP地址、子网掩码、网络号、主机号、网络地址、主机地址