UNIX 上的延时函数有好几种(2)

C代码
unsigned int sleep(unsigned int seconds);   
  
void usleep(unsigned long usec);   
  
int nanosleep(const struct timespec *req, struct timespec *rem);   
  
int select(int n, fd_set *readfds,fd_set *writefds,fd_set *exceptfds,   
struct timeval *timeout);   
  
int pselect(int n,fd_set *readfds,fd_set *writefds,fd_set *exceptfds,   
 const struct timespec *timeout, const sigset_t *sigmask); 
unsigned int sleep(unsigned int seconds);

void usleep(unsigned long usec);

int nanosleep(const struct timespec *req, struct timespec *rem);

int select(int n, fd_set *readfds,fd_set *writefds,fd_set *exceptfds,
struct timeval *timeout);

int pselect(int n,fd_set *readfds,fd_set *writefds,fd_set *exceptfds,
 const struct timespec *timeout, const sigset_t *sigmask);

alarm函数是信号方式的延迟,这种方式不直观,这里不说了。
仅通过函数原型中时间参数类型,可以猜测sleep可以精确到秒级,usleep/select可以精确到微妙级,nanosleep和pselect可以精确到纳秒级。
而 实际实现中,linux上的nanosleep和alarm相同,都是基于内核时钟机制实现,受linux内核时钟实现的影响,并不能达到纳秒级的精度, man nanosleep也可以看到这个说明,man里给出的精度是:Linux/i386上是10 ms ,Linux/Alpha上是1ms。 

测试了不同延迟函数之间的精确度。文章给出的结论是linux上精度最高的是select,10ms级别。我在本机器测试select和pselect相 当,都达到了1ms级的精度,精度高于文章中给出的10ms,sleep在秒级以上和usleep/nanosleep相当。下面贴下我机器上1ms时候 的测试结果,其他不贴了:

C代码
sleep           1000          0      -1000    
usleep           1000       2974       1974    
nanosleep        1000       2990       1990    
select           1000        991         -9    
pselect           1000        990        -10    
gettimeofday           1000       1000          0 
sleep           1000          0      -1000
usleep           1000       2974       1974
nanosleep        1000       2990       1990
select           1000        991         -9
pselect           1000        990        -10
gettimeofday           1000       1000          0

而使用gettimeofday循环不停检测时间,可精确微秒级,不过不适宜用来做定时器模块。
因此后面的定时期模块将选择select为延迟函数。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wwpzfz.html