First of all, I would like to thank the following two blogs for putting me out of a major misunderstanding:
Http://www.cppblog.com/kongque/archive/2011/01/18/138765.aspx
Http://blog.csdn.net/zjwoody/article/details/7882240
In one of my projects, because of the need to communicate with the serial port, every read/write operation requires a delay of usleep (1000) = 1 ms, but the traffic is very large, every job has about 300 such communications, which takes about Ms.
However, when strace is used to print out the system function call, it is found that the actual latency is close to 900 ms. Only by carefully observing the strace log can we find that every time usleep (1000000) is delayed by 2 ms, the usleep is not accurate only after searching the Internet.
1. the sleep precision is second 2. the precision of usleep is subtle and inaccurate. the Select precision is subtle, precise struct timeval delay; delay. TV _sec = 0; delay. TV _usec = 20*1000; // 20 MS select (0, null, & delay); 4. the precision of nanosleep is nanoseconds, but nanosleep should be used instead of usleep and sleep if possible in UNIX and Linux systems. When using nanosleep, you should pay attention to the returned value and error code; otherwise, the CPU usage may be 100%.
This is mentioned in the first blog, and then the test code provided in the second blog, I made a few changes (the original author did not print the usleep (0) Information), the Code is as follows:
/* Make: gcc-O test_sleep test_sleep.c */# 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> # define print_useage {\ fprintf (stderr, "\ n usage: % s USEC", argv [0]); \ fprintf (stderr, "\ 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,100 000, 50000,100 00, 1000,900,500,100, 10, 1, 0}; int nreduce = 0; /* Error */# If 0 if (argc <2) {print_useage; exit (1);} ndelay = atoi (argv [1]); # endif fprintf (stderr, "% 18 S % 12 S % 12 S % 12s \ n", "function", "Time (USEC)", "Realtime", "reduce"); fprintf (stderr, "token \ n"); for (I = 0; I <11; 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 ); /* 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, & 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 ;}
The program is shown as follows:
[root@localhost test]# ./sleep_com function time(usec) realTime reduce-------------------------------------------------------------------/t usleep 500000 501575 1575/t nanosleep 500000 501861 1861/t select 500000 499893 -107/t usleep 100000 101933 1933/t nanosleep 100000 101957 1957/t select 100000 99946 -54/t usleep 50000 51954 1954/t nanosleep 50000 51962 1962/t select 50000 49991 -9/t usleep 10000 11941 1941/t nanosleep 10000 11973 1973/t select 10000 9974 -26/t usleep 1000 2976 1976/t nanosleep 1000 2974 1974/t select 1000 993 -7/t usleep 900 1968 1068/t nanosleep 900 1978 1078/t select 900 966 66/t usleep 500 1971 1471/t nanosleep 500 1973 1473/t select 500 992 492/t usleep 100 1970 1870/t nanosleep 100 1979 1879/t select 100 968 868/t usleep 10 1972 1962/t nanosleep 10 1974 1964/t select 10 993 983/t usleep 1 1969 1968/t nanosleep 1 1983 1982/t select 1 960 959/t usleep 0 988 988/t nanosleep 0 961 961/t select 0 5 5/t usleep 0 971 971
The above table shows that the actual latency of usleep (1000) is nearly 3 ms.