/*
make: gcc -o test_sleep test_sleep.c
*/
/* #include "comm_main.h" */
#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>;linux
#define PRINT_USEAGE { \
fprintf(stderr,"\n Usage: %s usec ",argv[0]); \
fprintf(stderr,"\n\n");\
}安全
int
main (int argc, char **argv)
{
unsigned int nTimeTestSec = 0; /* sec */
unsigned int nTimeTest = 0; /* usec */
struct timeval tvBegin;
struct timeval tvNow;
int ret = 0;
unsigned int nDelay = 0; /* usec */
fd_set rfds;
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; /* 偏差 */多線程
#if 0
if (argc < 2)
{
PRINT_USEAGE;
exit (1);
}
nDelay = atoi (argv[1]);
#endif函數
fprintf (stderr, "%18s%12s%12s%12s\n", "function", "time(usec)", "realTime",
"reduce");
fprintf (stderr,
"-------------------------------------------------------------------\n");oop
for (i = 0; i < 20; i++)
{
if (delay[i] <= 0)
break;
nDelay = delay[i];測試
/* test usleep */
gettimeofday (&tvBegin, NULL);
ret = usleep (nDelay);
if (-1 == ret)
{
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);spa
/* test nanosleep */
gettimeofday (&tvBegin, NULL);
req.tv_sec = nDelay / 1000000;
req.tv_nsec = (nDelay % 1000000) * 1000;
ret = nanosleep (&req, NULL);
if (-1 == ret)
{
fprintf (stderr, "\t nanosleep %8u not support\n", nDelay);
}
else
{
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 */
gettimeofday (&tvBegin, NULL);
FD_ZERO (&rfds);
FD_SET (fd, &rfds);
tv.tv_sec = 0;
tv.tv_usec = nDelay;
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);進程
}文檔
return 0;
}
---------------------------------------------------------------------------------------------------------------------------------------------------
測試
IBM AIX 3.4 單CPU
sleep 能夠在多線程中使用,只阻塞本線程,不影響所屬進程中的其它線程
不支持 nanosleep
支持 usleep 和 select
如下采用 gettimeofday 對 usleep 和 select 的實際精確狀況進行測試分析
function time(usec) realTime reduce
-------------------------------------------------------------------
usleep 500000 500026 26
nanosleep 500000 not support
select 500000 500026 26
usleep 100000 100021 21
nanosleep 100000 not support
select 100000 100025 25
usleep 50000 50021 21
nanosleep 50000 not support
select 50000 50107 107
usleep 10000 10099 99
nanosleep 10000 not support
select 10000 10025 25
usleep 1000 1021 21
nanosleep 1000 not support
select 1000 1024 24
usleep 900 920 20
nanosleep 900 not support
select 900 1024 124
usleep 500 523 23
nanosleep 500 not support
select 500 1024 524
usleep 100 119 19
nanosleep 100 not support
select 100 1023 923
usleep 10 31 21
nanosleep 10 not support
select 10 1024 1014
usleep 1 19 18
nanosleep 1 not support
select 1 1026 1025
由此能夠得出,在AIX 3.4下:
select 只能精確到毫秒級別
usleep 能夠精確到微秒級
在1毫秒以上,二者的精確度基本同樣
同上,在 linux 2.4.20-8smp 雙CPU 下測試
function time(usec) realTime reduce
-------------------------------------------------------------------
usleep 500000 506453 6453
nanosleep 500000 509930 9930
select 500000 499990 -10
usleep 100000 110023 10023
nanosleep 100000 109955 9955
select 100000 99992 -8
usleep 50000 59971 9971
nanosleep 50000 59990 9990
select 50000 50025 25
usleep 10000 19991 9991
nanosleep 10000 19988 9988
select 10000 9956 -44
usleep 1000 19990 18990
nanosleep 1000 19989 18989
select 1000 10024 9024
usleep 900 20009 19109
nanosleep 900 19972 19072
select 900 9943 9043
usleep 500 19975 19475
nanosleep 500 19971 19471
select 500 10012 9512
usleep 100 19975 19875
nanosleep 100 19976 19876
select 100 9943 9843
usleep 10 19988 19978
nanosleep 10 19961 19951
select 10 10011 10001
usleep 1 19978 19977
nanosleep 1 19985 19984
select 1 9932 9931
在 2.4.21-4.ELsmp #1 SMP 4 CPU 下測試
function time(usec) realTime reduce
-------------------------------------------------------------------
usleep 500000 501267 1267
nanosleep 500000 509964 9964
select 500000 499981 -19
usleep 100000 109944 9944
nanosleep 100000 109925 9925
select 100000 99963 -37
usleep 50000 59904 9904
nanosleep 50000 59973 9973
select 50000 49956 -44
usleep 10000 19988 9988
nanosleep 10000 20008 10008
select 10000 10020 20
usleep 1000 19988 18988
nanosleep 1000 19980 18980
select 1000 9943 8943
usleep 900 19975 19075
nanosleep 900 19986 19086
select 900 9905 9005
usleep 500 19989 19489
nanosleep 500 19910 19410
select 500 10000 9500
usleep 100 19355 19255
nanosleep 100 19902 19802
select 100 9988 9888
usleep 10 19977 19967
nanosleep 10 19988 19978
select 10 9943 9933
usleep 1 20007 20006
nanosleep 1 19947 19946
select 1 9980 9979
由此能夠得出以下結論,在 linux 2.4 下:
一、支持 usleep,nanosleep,select
二、select 的 精確度爲 10毫秒。在10毫秒以上很精確
三、usleep, nanosleep 很不精確
一樣,經過其它測試程序能得出以下結論:
sleep 能夠在多線程中使用,只阻塞本線程,不影響所屬進程中的其它線程
usleep()有有很大的問題
還好,POSIX規範中有一個很好用的函數,nanosleep(),該函數沒有usleep()的這些缺點,它的精度是納秒級。在Solaris的多線程環境下編譯器會自動把usleep()鏈接成nanosleep()。
Linux下短延時推薦使用select函數.