最近工做中須要在ACodec中起一個pthread,並每間隔100ms統計一次buffer的狀態,在程序中使用pthread_cond_timedwait來設置時間間隔,但在使用中發現當超時時間設置成1秒如下的值時,沒法獲得想要的效果,具體表現爲,沒有wait足夠的時間就被喚醒,且返回值正確。函數
查看pthread_cond_timedwait的函數原型:spa
1 int pthread_cond_timedwait(pthread_cond_t *cond_interface, 2 pthread_mutex_t * mutex, 3 const timespec *abstime)
abstime是一個絕對時間,struct timespce的原型爲:code
1 struct timespec { 2 time_t tv_sec; /* Seconds */ 3 long tv_nsec; /* Nanoseconds */ 4 };
其中tv_sec是秒,tv_nsec是納秒(即1000,000,000分之一秒).blog
首先看一下我以前錯誤的代碼:get
1 long timeout_ms = 100; // wait time 100ms 2 struct timespec abstime; 3 abstime.tv_sec = time(NULL) + timeout_ms / 1000; 4 abstime.tv_nsec = (timeout_ms % 1000) * 1000000; 5 pthread_cond_timedwait(&cond, &mutex, &abstime);
以上代碼有問題,主要是由於time(NULL)的返回結果的精度是秒級的,那麼若是當前時間是m秒+n毫秒,那麼實際等待的時間只是timeout_ms – n,且還有可能發生n > timeout_ms的狀況,這種情形下,若是這段代碼處在一處while循環內,則會形成大量的pthread_cond_timedwait系統調用,並形成大量的context switch,系統CPU會佔用很高。原型
正確的代碼應該改成以下:it
1 struct timespec abstime; 2 struct timeval now; 3 long timeout_ms = 100; // wait time 100ms 4 gettimeofday(&now, NULL); 5 long nsec = now.tv_usec * 1000 + (timeout_ms % 1000) * 1000000; 6 abstime.tv_sec=now.tv_sec + nsec / 1000000000 + timeout_ms / 1000; 7 abstime.tv_nsec=nsec % 1000000000; 8 pthread_cond_timedwait(&cond, &mutex, &abstime);
經過gettimeofday得到精確到微秒(1000,000分之一秒)的時間數據,並處理不足一秒加上超時時間超過一秒的狀況(即tv_sec上須要加上nsec/1000000000)。class