转自:
http://blog.csdn.net/joker0910/article/details/7240940
今天在公司代码中看到了使用select函数的超时功能作定时器的用法,便整理了如下几个Linux下的微秒级别的定时器。在我的Ubutu10.10 双核环境中,编译通过。
[cpp] view
plaincopy
-
-
-
-
-
-
-
-
-
-
-
-
#include
-
#include
-
#include
-
#include
-
#include
-
#include
-
#include
-
#include
-
#include
-
-
-
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
", "fuction", "time(usec)", "realtime", "reduce");
-
fprintf(stderr, "----------------------------------------------------
");
-
for (i = 0; i < 20; i++)
-
{
-
if (delay[i] <= 0)
-
break;
-
nDelay = delay[i];
-
-
gettimeofday(&tvBegin, NULL);
-
ret = usleep(nDelay);
-
if(ret == -1)
-
{
-
fprintf(stderr, "usleep error, errno=%d [%s]
", 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, " usleep %8u %8u %8d
", nDelay, nTimeTest,nReduce);
-
-
-
req.tv_sec = nDelay/1000000;
-
req.tv_nsec = (nDelay%1000000) * 1000;
-
-
gettimeofday(&tvBegin, NULL);
-
ret = nanosleep(&req, NULL);
-
if (-1 == ret)
-
{
-
fprintf (stderr, " nanousleep %8u not support
", nDelay);
-
}
-
gettimeofday(&tvNow, NULL);
-
nTimeTest = (tvNow.tv_sec - tvBegin.tv_sec) * 1000000 + tvNow.tv_usec - tvBegin.tv_usec;
-
nReduce = nTimeTest - nDelay;
-
fprintf (stderr, " nanosleep %8u %8u %8d
", nDelay, nTimeTest,nReduce);
-
-
-
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]
", 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, " select %8u %8u %8d
", nDelay, nTimeTest,nReduce);
-
-
-
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]
", 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, " pselect %8u %8u %8d
", nDelay, nTimeTest,nReduce);
-
-
fprintf (stderr, "--------------------------------
");
-
-
}
-
-
return 0;
-
}
老大建议我们在对精度要求较高的情况下使用select()作为定时器,最大的好处
就是不会影响信号处理,线程安全,而且精度能得到保证。在这个实验中,当时间延时时间较长时,select和pselect表现较差,当时间小于1毫秒时,他们的精确度便提高了,表现与usleep、nanosleep不相上下,有时精度甚至超过后者。