zoukankan      html  css  js  c++  java
  • linux 下高精度时间

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

    [cpp] view plain copy
     
    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.   
    22.   
    23. int main(int argc, char **argv)  
    24. {  
    25.     unsigned int nTimeTestSec = 0;  
    26.     unsigned int nTimeTest = 0;  
    27.     struct timeval tvBegin;  
    28.     struct timeval tvNow;  
    29.     int ret = 0;  
    30.     unsigned int nDelay = 0;  
    31.     struct timeval tv;  
    32.     int fd = 1;  
    33.     int i = 0;  
    34.     struct timespec req;  
    35.   
    36.     unsigned int delay[20] =   
    37.         {500000, 100000, 50000, 10000, 1000, 900, 500, 100, 10, 1, 0};  
    38.     int nReduce = 0; //误差  
    39.   
    40.     fprintf(stderr, "%19s%12s%12s%12s ", "fuction", "time(usec)", "realtime", "reduce");  
    41.     fprintf(stderr, "---------------------------------------------------- ");  
    42.     for (i = 0; i < 20; i++)  
    43.     {  
    44.         if (delay[i] <= 0)  
    45.             break;  
    46.         nDelay = delay[i];  
    47.         //test sleep  
    48.         gettimeofday(&tvBegin, NULL);  
    49.         ret = usleep(nDelay);  
    50.         if(ret == -1)  
    51.         {  
    52.             fprintf(stderr, "usleep error, errno=%d [%s] ", errno, strerror(errno));  
    53.         }  
    54.         gettimeofday(&tvNow, NULL);  
    55.         nTimeTest = (tvNow.tv_sec - tvBegin.tv_sec) * 1000000 + tvNow.tv_usec - tvBegin.tv_usec;  
    56.         nReduce = nTimeTest - nDelay;  
    57.   
    58.          fprintf (stderr, "  usleep       %8u   %8u   %8d ", nDelay, nTimeTest,nReduce);  
    59.   
    60.          //test nanosleep  
    61.          req.tv_sec = nDelay/1000000;  
    62.          req.tv_nsec = (nDelay%1000000) * 1000;  
    63.   
    64.          gettimeofday(&tvBegin, NULL);  
    65.          ret = nanosleep(&req, NULL);  
    66.          if (-1 == ret)  
    67.          {  
    68.             fprintf (stderr, "  nanousleep   %8u   not support ", nDelay);  
    69.          }  
    70.          gettimeofday(&tvNow, NULL);  
    71.          nTimeTest = (tvNow.tv_sec - tvBegin.tv_sec) * 1000000 + tvNow.tv_usec - tvBegin.tv_usec;  
    72.          nReduce = nTimeTest - nDelay;  
    73.          fprintf (stderr, "  nanosleep    %8u   %8u   %8d ", nDelay, nTimeTest,nReduce);  
    74.   
    75.          //test select  
    76.          tv.tv_sec = 0;  
    77.          tv.tv_usec = nDelay;  
    78.   
    79.          gettimeofday(&tvBegin, NULL);  
    80.          ret = select(0, NULL, NULL, NULL, &tv);  
    81.          if (-1 == ret)  
    82.          {  
    83.             fprintf(stderr, "select error. errno = %d [%s] ", errno, strerror(errno));  
    84.          }  
    85.   
    86.          gettimeofday(&tvNow, NULL);  
    87.          nTimeTest = (tvNow.tv_sec - tvBegin.tv_sec) * 1000000 + tvNow.tv_usec - tvBegin.tv_usec;  
    88.          nReduce = nTimeTest - nDelay;  
    89.          fprintf (stderr, "  select       %8u   %8u   %8d ", nDelay, nTimeTest,nReduce);  
    90.   
    91.          //pselcet  
    92.          req.tv_sec = nDelay/1000000;  
    93.          req.tv_nsec = (nDelay%1000000) * 1000;  
    94.   
    95.          gettimeofday(&tvBegin, NULL);  
    96.          ret = pselect(0, NULL, NULL, NULL, &req, NULL);  
    97.          if (-1 == ret)  
    98.          {  
    99.             fprintf(stderr, "select error. errno = %d [%s] ", errno, strerror(errno));  
    100.          }  
    101.   
    102.          gettimeofday(&tvNow, NULL);  
    103.          nTimeTest = (tvNow.tv_sec - tvBegin.tv_sec) * 1000000 + tvNow.tv_usec - tvBegin.tv_usec;  
    104.          nReduce = nTimeTest - nDelay;  
    105.          fprintf (stderr, "  pselect      %8u   %8u   %8d ", nDelay, nTimeTest,nReduce);  
    106.   
    107.          fprintf (stderr, "-------------------------------- ");  
    108.   
    109.     }  
    110.       
    111.     return 0;  
    112. }  

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

  • 相关阅读:
    linux集群实施与部署-----Nginx
    以太网链路聚合简单配置
    配置基于源地址的策略路由
    shell --Day 6
    ps初学--Day 1部分工具使用
    shell --Day 5
    shell ——Day 4
    shell——Day3
    shell——Day 2
    初学shell——Day1
  • 原文地址:https://www.cnblogs.com/jkred369/p/6861586.html
Copyright © 2011-2022 走看看