您的位置:首页 > 运维架构 > Linux

Linux下的微秒级定时器: usleep, nanosleep, select, pselect

2013-09-02 16:31 621 查看
转自:http://blog.csdn.net/joker0910/article/details/7240940

 


Linux下的微秒级定时器: usleep, nanosleep, select, pselect

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

[cpp] view
plaincopy

/* 

 * @FileName: test_sleep.c 

 * @Author: wzj 

 * @Brief:  

 *    

 *   

 * @History:  

 *  

 * @Date: 2012年02月07日星期二22:20:00 

 *  

 */   

#include<stdio.h>  

#include<stdlib.h>  

#include<time.h>  

#include<sys/time.h>  

#include<errno.h>  

#include<string.h>  

#include<unistd.h>  

#include<sys/types.h>  

#include<sys/select.h>  

  

  

int main(int argc, char **argv)  

{  

    unsigned int nTimeTestSec = 0;  

    unsigned int nTimeTest = 0;  

    struct timeval tvBegin;  

    struct timeval tvNow;  

    int ret = 0;  

    unsigned int nDelay = 0;  

    struct timeval tv;  

    int fd = 1;  

    int i = 0;  

    struct timespec req;  

  

    unsigned int delay[20] =   

        {500000, 100000, 50000, 10000, 1000, 900, 500, 100, 10, 1, 0};  

    int nReduce = 0; //误差  

  

    fprintf(stderr, "%19s%12s%12s%12s\n", "fuction", "time(usec)", "realtime", "reduce");  

    fprintf(stderr, "----------------------------------------------------\n");  

    for (i = 0; i < 20; i++)  

    {  

        if (delay[i] <= 0)  

            break;  

        nDelay = delay[i];  

        //test sleep  

        gettimeofday(&tvBegin, NULL);  

        ret = usleep(nDelay);  

        if(ret == -1)  

        {  

            fprintf(stderr, "usleep error, errno=%d [%s]\n", errno, strerror(errno));  

        }  

        gettimeofday(&tvNow, NULL);  

        nTimeTest = (tvNow.tv_sec - tvBegin.tv_sec) * 1000000 + tvNow.tv_usec - tvBegin.tv_usec;  

        nReduce = nTimeTest - nDelay;  

  

         fprintf (stderr, "\t usleep       %8u   %8u   %8d\n", nDelay, nTimeTest,nReduce);  

  

         //test nanosleep  

         req.tv_sec = nDelay/1000000;  

         req.tv_nsec = (nDelay%1000000) * 1000;  

  

         gettimeofday(&tvBegin, NULL);  

         ret = nanosleep(&req, NULL);  

         if (-1 == ret)  

         {  

            fprintf (stderr, "\t nanousleep   %8u   not support\n", nDelay);  

         }  

         gettimeofday(&tvNow, NULL);  

         nTimeTest = (tvNow.tv_sec - tvBegin.tv_sec) * 1000000 + tvNow.tv_usec - tvBegin.tv_usec;  

         nReduce = nTimeTest - nDelay;  

         fprintf (stderr, "\t nanosleep    %8u   %8u   %8d\n", nDelay, nTimeTest,nReduce);  

  

         //test select  

         tv.tv_sec = 0;  

         tv.tv_usec = nDelay;  

  

         gettimeofday(&tvBegin, NULL);  

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

         if (-1 == ret)  

         {  

            fprintf(stderr, "select error. errno = %d [%s]\n", errno, strerror(errno));  

         }  

  

         gettimeofday(&tvNow, NULL);  

         nTimeTest = (tvNow.tv_sec - tvBegin.tv_sec) * 1000000 + tvNow.tv_usec - tvBegin.tv_usec;  

         nReduce = nTimeTest - nDelay;  

         fprintf (stderr, "\t select       %8u   %8u   %8d\n", nDelay, nTimeTest,nReduce);  

  

         //pselcet  

         req.tv_sec = nDelay/1000000;  

         req.tv_nsec = (nDelay%1000000) * 1000;  

  

         gettimeofday(&tvBegin, NULL);  

         ret = pselect(0, NULL, NULL, NULL, &req, NULL);  

         if (-1 == ret)  

         {  

            fprintf(stderr, "select error. errno = %d [%s]\n", errno, strerror(errno));  

         }  

  

         gettimeofday(&tvNow, NULL);  

         nTimeTest = (tvNow.tv_sec - tvBegin.tv_sec) * 1000000 + tvNow.tv_usec - tvBegin.tv_usec;  

         nReduce = nTimeTest - nDelay;  

         fprintf (stderr, "\t pselect      %8u   %8u   %8d\n", nDelay, nTimeTest,nReduce);  

  

         fprintf (stderr, "--------------------------------\n");  

  

    }  

      

    return 0;  

}  

    老大建议我们在对精度要求较高的情况下使用select()作为定时器,最大的好处就是不会影响信号处理,线程安全,而且精度能得到保证。在这个实验中,当时间延时时间较长时,select和pselect表现较差,当时间小于1毫秒时,他们的精确度便提高了,表现与usleep、nanosleep不相上下,有时精度甚至超过后者。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: