在编写程序时,我们经常会用到定时器。首先看看select函数原型如下:

int select(int nfds, fd_set *readfds, fd_set *writefds,

fd_set *exceptfds, struct timeval *timeout);

参数说明:

slect的第一个参数nfds为fdset集合中最大描述符值加1,fdset是一个位数组,其大小限制为__FD_SETSIZE(1024),位数组的每一位代表其对应的描述符是否需要被检查。

select的第二三四个参数表示需要关注读、写、错误事件的文件描述符位数组,这些参数既是输入参数也是输出参数,可能会被内核修改用于标示哪些描述符上发生了关注的事件。所以每次调用select前都需重新初始化fdset。

timeout参数为超时时间,该结构会被内核修改,其值为超时剩余的时间。

利用select实现定时器,需要利用其timeout参数,注意到:

1)select函数使用了一个结构体timeval作为其参数。

2)select函数会更新timeval的值,timeval保持的值为剩余时间。

如果我们指定了参数timeval的值,而将其他参数都置为0或者NULL,那么在时间耗尽后,select函数便返回,基于这一点,我们可以利用select实现精确定时。

timeval的结构如下:

struct timeval{

long tv_sec;/*secons*

long tv_usec;/*microseconds*/

}

我们可以看出其精确到microseconds也即微妙。

一、秒级定时器

void seconds_sleep(unsigned seconds){

struct timeval tv;

tv.tv_sec=seconds;

tv.tv_usec=0;

int err;

do{

err=select(0,NULL,NULL,NULL,&tv);

}while(err<0 && errno==EINTR);

}

二、毫秒级别定时器

void milliseconds_sleep(unsigned long mSec){

struct timeval tv;

tv.tv_sec=mSec/1000;

tv.tv_usec=(mSec%1000)*1000;

int err;

do{

err=select(0,NULL,NULL,NULL,&tv);

}while(err<0 && errno==EINTR);

}

三、微妙级别定时器

void microseconds_sleep(unsigned long uSec){

struct timeval tv;

tv.tv_sec=uSec/1000000;

tv.tv_usec=uSec%1000000;

int err;

do{

err=select(0,NULL,NULL,NULL,&tv);

}while(err<0 && errno==EINTR);

}

现在我们来编写几行代码看看定时效果吧。

#include

#include

#include

int main()

{

int i;

for(i=0;i<5;++i){

printf("%d\n",i);

//seconds_sleep(1);

//milliseconds_sleep(1500);

microseconds_sleep(1900000);

}

}

注:timeval结构体中虽然指定了一个微妙级别的分辨率,但内核支持的分别率往往没有这么高,很多unix内核将超时值向上舍入成10ms的倍数。此外,加上内核调度延时现象,即定时器时间到后,内核还需要花一定时间调度相应进程的运行。因此,定时器的精度,最终还是由内核支持的分别率决定。

分类: Linux

linux 内核定时器精度_linux使用select实现精确定时器详解相关推荐

  1. linux减小根目录空间_Linux目录结构及文件基本操作详解

    Linux 目录结构及文件 在 windows 平台下,打开"计算机",我们看到的是一个个的盘符: 在 Linux 下,我们是看不到这些盘符,我们看到的是文件夹(目录): 在早期的 ...

  2. linux恢复mysql配置文件_linux下mysql配置文件my.cnf详解【转】

    basedir = path 使用给定目录作为根目录(安装目录). character-sets-dir = path 给出存放着字符集的目录. datadir = path 从给定目录读取数据库文件 ...

  3. linux内核镜像的分层,Docker镜像分层的原理详解

    base镜像 base镜像有两层含义: 不依赖其他镜像,从scratch构建 其他镜像可以之为基础进行扩展 所以,base镜像一般都是各种Linux发行版本的Docker镜像,比如:Ubuntu,De ...

  4. linux运行python乱码_linux下python中文乱码解决方案详解

    1. 场景描述 linux服务器下安装了Anaconda3,执行Pyhton的K-means算法,结果出现如下图的中文字符乱码.上次已经解决了,忘记记录解决流程了,这次配置了一台新的服务器,又出现,默 ...

  5. linux内核移植与开发板,Linux 2.6.36内核移植飞凌OK6410开发板完整步骤详解

    Linux 2.6.36内核移植飞凌OK6410开发板完整步骤详解 [复制链接] 今天终于让Linux内核在飞凌的板子上跑起来了,想来也是艰辛,为了移植成功,断断续续做了将近两个月的努力,期间郁闷不可 ...

  6. (转)Linux下PS1、PS2、PS3、PS4使用详解

    Linux下PS1.PS2.PS3.PS4使用详解 原文:http://www.linuxidc.com/Linux/2016-10/136597.htm 1.PS1--默认提示符 如下所示,可以通过 ...

  7. Linux 高可用(HA)集群之Pacemaker详解

    大纲 说明:本来我不想写这篇博文的,因为前几篇博文都有介绍pacemaker,但是我觉得还是得写一下,试想应该会有博友需要,特别是pacemaker 1.1.8(CentOS 6.4)以后,pacem ...

  8. mysql select 缓存_mysql select缓存机制使用详解

    mysql Query Cache 默认为打开.从某种程度可以提高查询的效果,但是未必是最优的解决方案,如果有的大量的修改和查询时,由于修改造成的cache失效,会给服务器造成很大的开销,可以通过qu ...

  9. linux下grep文件内容搜索工具及基本正则表达式详解

    linux下grep文件内容搜索工具及基本正则表达式详解 grep命令: 根据模式(文本字符和基本正则表达式的元字符组合而成之匹配条件)搜索文本, 并将符合模式的文本行显示出来. 格式:grep [选 ...

最新文章

  1. 图的遍历——广度优先搜索(Breadth First Search)
  2. MATLAB table数据结构 首篇
  3. 5月19-20日WebRTCon 2018 梳理全球WebRTC技术实践与案例
  4. 2021 icme_2021第十届制造工程与工艺国际会议(ICMEP 2021)
  5. 服务器日志记录_5种改善服务器日志记录的技术
  6. 使用MUI框架,模拟手机端的下拉刷新,上拉加载操作。
  7. 解析取值_圆锥曲线——高中解析几何全归纳
  8. jquery attr
  9. Android Activity中重写onCreateOptionsMenu不显示菜单按钮
  10. jsp+mysql 数据库操作
  11. python处理xls到csv文件
  12. 阿里云oss文件分片、断点续传上传
  13. “去中心化”和“分布式”的区别
  14. SpringSecurity,jwt oathu sso,YeZiJie
  15. VSCode ctrl+鼠标左键无法跳转,F12可以跳转
  16. 关于七彩虹显卡命名解说
  17. 【深度学习】VGG16--slim
  18. 使用Prometheus监控web站点及证书过期
  19. 用C++写出求矩形和圆形面积的程序
  20. AC---上网行为管理

热门文章

  1. JavaScript程序开发(十四)—函数声明与函数表达式
  2. MongoDB-数据库-mongoose-图形化操作
  3. 变成小白的第一本Python入门书,第五章循环与判断课后题答案
  4. 你活了多久----快用Python计算一下日期
  5. 顺序循环队列的基本操作
  6. 双向链表中插入结点并输出
  7. 对计算器软件的测试报告,Win7计算器软件测试报告.doc
  8. linux下dns服务器安装,Linux下DNS服务器安装配置方法详细介绍
  9. HTML基础知识(w3school)
  10. 【Docker】Segmentation Fault or Critical Error encountered. Dumping core and abort