今天在公司代码中看到了使用select函数的超时功能作定时器的用法,便整理了如下几个Linux下的微秒级别的定时器。在我的Ubutu10.10 双核环境中,编译通过。

  1. /*
  2. * @FileName: test_sleep.c
  3. * @Author: wzj
  4. * @Brief:
  5. *
  6. *
  7. * @History:
  8. *
  9. * @Date: 2012年02月07日星期二22:20:00
  10. *
  11. */
  12. #include<stdio.h>
  13. #include<stdlib.h>
  14. #include<time.h>
  15. #include<sys/time.h>
  16. #include<errno.h>
  17. #include<string.h>
  18. #include<unistd.h>
  19. #include<sys/types.h>
  20. #include<sys/select.h>
  21. int main(int argc, char **argv)
  22. {
  23. unsigned int nTimeTestSec = 0;
  24. unsigned int nTimeTest = 0;
  25. struct timeval tvBegin;
  26. struct timeval tvNow;
  27. int ret = 0;
  28. unsigned int nDelay = 0;
  29. struct timeval tv;
  30. int fd = 1;
  31. int i = 0;
  32. struct timespec req;
  33. unsigned int delay[20] =
  34. {500000, 100000, 50000, 10000, 1000, 900, 500, 100, 10, 1, 0};
  35. int nReduce = 0; //误差
  36. fprintf(stderr, "%19s%12s%12s%12s\n", "fuction", "time(usec)", "realtime", "reduce");
  37. fprintf(stderr, "----------------------------------------------------\n");
  38. for (i = 0; i < 20; i++)
  39. {
  40. if (delay[i] <= 0)
  41. break;
  42. nDelay = delay[i];
  43. //test sleep
  44. gettimeofday(&tvBegin, NULL);
  45. ret = usleep(nDelay);
  46. if(ret == -1)
  47. {
  48. fprintf(stderr, "usleep error, errno=%d [%s]\n", errno, strerror(errno));
  49. }
  50. gettimeofday(&tvNow, NULL);
  51. nTimeTest = (tvNow.tv_sec - tvBegin.tv_sec) * 1000000 + tvNow.tv_usec - tvBegin.tv_usec;
  52. nReduce = nTimeTest - nDelay;
  53. fprintf (stderr, "\t usleep       %8u   %8u   %8d\n", nDelay, nTimeTest,nReduce);
  54. //test nanosleep
  55. req.tv_sec = nDelay/1000000;
  56. req.tv_nsec = (nDelay%1000000) * 1000;
  57. gettimeofday(&tvBegin, NULL);
  58. ret = nanosleep(&req, NULL);
  59. if (-1 == ret)
  60. {
  61. fprintf (stderr, "\t nanousleep   %8u   not support\n", nDelay);
  62. }
  63. gettimeofday(&tvNow, NULL);
  64. nTimeTest = (tvNow.tv_sec - tvBegin.tv_sec) * 1000000 + tvNow.tv_usec - tvBegin.tv_usec;
  65. nReduce = nTimeTest - nDelay;
  66. fprintf (stderr, "\t nanosleep    %8u   %8u   %8d\n", nDelay, nTimeTest,nReduce);
  67. //test select
  68. tv.tv_sec = 0;
  69. tv.tv_usec = nDelay;
  70. gettimeofday(&tvBegin, NULL);
  71. ret = select(0, NULL, NULL, NULL, &tv);
  72. if (-1 == ret)
  73. {
  74. fprintf(stderr, "select error. errno = %d [%s]\n", errno, strerror(errno));
  75. }
  76. gettimeofday(&tvNow, NULL);
  77. nTimeTest = (tvNow.tv_sec - tvBegin.tv_sec) * 1000000 + tvNow.tv_usec - tvBegin.tv_usec;
  78. nReduce = nTimeTest - nDelay;
  79. fprintf (stderr, "\t select       %8u   %8u   %8d\n", nDelay, nTimeTest,nReduce);
  80. //pselcet
  81. req.tv_sec = nDelay/1000000;
  82. req.tv_nsec = (nDelay%1000000) * 1000;
  83. gettimeofday(&tvBegin, NULL);
  84. ret = pselect(0, NULL, NULL, NULL, &req, NULL);
  85. if (-1 == ret)
  86. {
  87. fprintf(stderr, "select error. errno = %d [%s]\n", errno, strerror(errno));
  88. }
  89. gettimeofday(&tvNow, NULL);
  90. nTimeTest = (tvNow.tv_sec - tvBegin.tv_sec) * 1000000 + tvNow.tv_usec - tvBegin.tv_usec;
  91. nReduce = nTimeTest - nDelay;
  92. fprintf (stderr, "\t pselect      %8u   %8u   %8d\n", nDelay, nTimeTest,nReduce);
  93. fprintf (stderr, "--------------------------------\n");
  94. }
  95. return 0;
  96. }

老大建议我们在对精度要求较高的情况下使用select()作为定时器,最大的好处就是不会影响信号处理,线程安全,而且精度能得到保证。在这个实验中,当时间延时时间较长时,select和pselect表现较差,当时间小于1毫秒时,他们的精确度便提高了,表现与usleep、nanosleep不相上下,有时精度甚至超过后者

linux 下高精度时间的更多相关文章

  1. Linux下长时间ping网络加时间戳并记录到文本

    Linux下长时间ping网络加时间戳并记录到文本   由于一些原因,比如需要检查网络之间是否存在掉包等问题,会长时间去ping一个地址,由于会输出大量的信息而且最好要有时间戳,因此我们可以使用简单的 ...

  2. Linux下精确控制时间的函数

    Linux下精确控制时间的函数 在测试程序接口运行时间的时候,常用time,gettimeofday等函数,但是这些函数在程序执行的时候是耗费时间的,如果仅仅测试时间还行,但是如果程序中用到时间控制类 ...

  3. Linux下设置时间

    Linux下设置时间 提供两种最根本有效的方式,就是更改时区.这里以更改为国内上海时间例子,其他地方时区同理. 方法一 备份文件 mv /etc/localtime /etc/localtime.ba ...

  4. Linux下系统时间函数、DST等相关问题总结(转)

    Linux下系统时间函数.DST等相关问题总结 下面这个结构体存储了跟时区相关的位移量(offset)以及是否存在DST等信息,根据所在的时区信息,很容易找到系统时间与UTC时间之间的时区偏移,另外根 ...

  5. linux下的时间

    1.linux下时间管理机制: 在系统启动时,Linux操作系统将时间从CMOS中读到系统时间变量中,以后修改时间通过修改系统时间实现.为了保持系统时间与CMOS时间的一致性,Linux每隔11分钟会 ...

  6. linux下修改时间和时区

    一.修改linux的时间在root用户下,使用date指令:date -s1.只修改日期,不修改时间,输入: date -s -- 2.只修改时间,输入: date -s :: 3.同时修改日期时间, ...

  7. linux下的时间管理概述

    2017/6/21 时间这一概念在生活中至关重要,而在操作系统中也同样重要,其在系统中的功能绝不仅仅是给用户提供时间这么简单,内核的许多机制都依赖于时间子系统.但凡是要在某个精确的时间执行某个事件,必 ...

  8. Linux下RTC时间的读写分析【转】

    本文转载自:http://blog.csdn.net/little_walt/article/details/52880840 Linux系统下包含两个时间:系统时间和RTC时间. 系统时间:是由主芯 ...

  9. LINUX下的时间与时区的设置

    在RHEL下,如果只装英文版系统,设置好时区以后(上海时间,UTC) 在命令行下用date命令查看,总是与实际的北京时间差8小时,其实硬件时间都是准确的.会带来视觉不便. 今天下决心解决此问题,不过也 ...

随机推荐

  1. kvm笔记

    1 virt-manager安装虚拟机无法使用键盘解决 今天远程用VNC登录服务器安装虚拟机,结果使用virt-manager安装虚拟机后在初始阶段无法使用键盘设置,这不雪崩了,后来来回试,找到了原因 ...

  2. 笔记--Day1--python基础1

    一.目录 1.Python介绍 python的创始人为吉多·范罗苏姆(Guido van Rossum),目前已经是使用频度特别高的开发语言. 主要应用领域: 云计算:云计算最火的语言,典型应用有Op ...

  3. NodeJS基础API-path相关的问题basename,extname,dirname,parse,format,sep,delimiter,win32,posix

    path 参考文档:http://nodejs.cn/api/path.html const {normalize} = require('path'); // ES6语法 // 相当于 const ...

  4. linux三剑客正则表达式

    ^:以...开头,^d,意思是以d开头.例如:ls  -F(-p) | grep " ^d " $:以...结尾,/$,意思是以/结尾.例如:ls -F(-p) | grep &q ...

  5. 【laravel】Laravel 5 TokenMismatchException on PHP 5.6.9

    When I realized this was only happening in IE and Chrome, but not Firefox, it led me to the fix. The ...

  6. [译]The Python Tutorial#4. More Control Flow Tools

    [译]The Python Tutorial#More Control Flow Tools 除了刚才介绍的while语句之外,Python也从其他语言借鉴了其他流程控制语句,并做了相应改变. 4.1 ...

  7. HBase0.94.2-cdh4.2.0需求评估测试报告1.0之二

    Hbase 配置文件: hbase-site.xml <configuration> <property> <name>hbase.cluster.distribu ...

  8. 1507: [NOI2003]Editor(块状链表)

    1507: [NOI2003]Editor Time Limit: 5 Sec  Memory Limit: 162 MBSubmit: 4157  Solved: 1677[Submit][Stat ...

  9. 实现socket并发的几种方法

    # 使用多进程实现socket聊天并发-server #服务端 import socket from multiprocessing import Process def server(conn,ad ...

  10. XP系统连接win10家庭版共享的打印机方法

    1.高级共享设置.按照win7正常设置."家庭网络"公用网络”“工作网络”之类的注意根据当前配置设置! 2.由于控制面板无法开启Guest账户.需要用任务管理器,运行cmd(管理员 ...