pthread_cond_timedwait時間設置


最近工作中需要在ACodec中起一個pthread,並每間隔100ms統計一次buffer的狀態,在程序中使用pthread_cond_timedwait來設置時間間隔,但在使用中發現當超時時間設置成1秒以下的值時,無法得到想要的效果,具體表現為,沒有wait足夠的時間就被喚醒,且返回值正確。

查看pthread_cond_timedwait的函數原型:

1 int pthread_cond_timedwait(pthread_cond_t *cond_interface,
2                            pthread_mutex_t * mutex,
3                            const timespec *abstime)

abstime是一個絕對時間,struct timespce的原型為:

1 struct timespec {
2   time_t tv_sec;    /* Seconds */
3   long tv_nsec;     /* Nanoseconds */
4 };

其中tv_sec是秒,tv_nsec是納秒(即1000,000,000分之一秒).

首先看一下我之前錯誤的代碼:

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會占用很高。

正確的代碼應該改為如下:

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)。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM