全网整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:400-708-3566

Linux模拟实现sleep函数

先来说说工作原理,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  # 函数  # 挂起  # 自定义  # 就会  # 可以实现  # 过了  # 才会  # 也能  # 不可以  # 我们可以  # 会让  # 解决问题  # 不做  # 在对  # 成为一个  # 定了  # 这两种  # 先来  # 正常运行  # 工作原理  # 大家多多 


相关文章: Python如何创建带属性的XML节点  大连 网站制作,大连天途有线官网?  如何自定义建站之星网站的导航菜单样式?  如何在阿里云虚拟机上搭建网站?步骤解析与避坑指南  香港服务器如何优化才能显著提升网站加载速度?  建站主机核心功能解析:服务器选择与网站搭建流程指南  Swift开发中switch语句值绑定模式  桂林网站制作公司有哪些,桂林马拉松怎么报名?  义乌企业网站制作公司,请问义乌比较好的批发小商品的网站是什么?  如何在Windows服务器上快速搭建网站?  沈阳个人网站制作公司,哪个网站能考到沈阳事业编招聘的信息?  小型网站制作HTML,*游戏网站怎么搭建?  广州顶尖建站服务:企业官网建设与SEO优化一体化方案  如何在宝塔面板中修改默认建站目录?  在线ppt制作网站有哪些软件,如何把网页的内容做成ppt?  怎么用手机制作网站链接,dw怎么把手机适应页面变成网页?  如何通过远程VPS快速搭建个人网站?  高端网站建设与定制开发一站式解决方案 中企动力  北京网站制作网页,网站升级改版需要多久?  建站一年半SEO优化实战指南:核心词挖掘与长尾流量提升策略  山东网站制作公司有哪些,山东大源集团官网?  建站10G流量真的够用吗?如何应对访问高峰?  建站之星导航菜单设置与功能模块配置全攻略  如何快速生成专业多端适配建站电话?  北京网站制作的公司有哪些,北京白云观官方网站?  网站建设制作需要多少钱费用,自己做一个网站要多少钱,模板一般多少钱?  如何配置FTP站点权限与安全设置?  制作无缝贴图网站有哪些,3dmax无缝贴图怎么调?  建站之星免费模板:自助建站系统与智能响应式一键生成  公司门户网站制作流程,华为官网怎么做?  建站之星伪静态规则如何设置?  建站之星安装路径如何正确选择及配置?  如何在IIS中新建站点并配置端口与物理路径?  香港服务器网站推广:SEO优化与外贸独立站搭建策略  如何在宝塔面板中创建新站点?  开封网站制作公司,网络用语开封是什么意思?  电商网站制作多少钱一个,电子商务公司的网站制作费用计入什么科目?  香港服务器部署网站为何提示未备案?  PHP正则匹配日期和时间(时间戳转换)的实例代码  在线教育网站制作平台,山西立德教育官网?  如何通过可视化优化提升建站效果?  C#如何使用XPathNavigator高效查询XML  无锡营销型网站制作公司,无锡网选车牌流程?  微信小程序制作网站有哪些,微信小程序需要做网站吗?  网站视频制作书签怎么做,ie浏览器怎么将网站固定在书签工具栏?  如何解决ASP生成WAP建站中文乱码问题?  已有域名和空间,如何快速搭建网站?  网站设计制作企业有哪些,抖音官网主页怎么设置?  哈尔滨网站建设策划,哈尔滨电工证查询网站?  如何在新浪SAE免费搭建个人博客? 

您的项目需求

*请认真填写需求信息,我们会在24小时内与您取得联系。