之前的一個項目遇到過一個linux線程中usleep卡死問題。
細查之下,發現usleep是非可重入的,也是非線程安全的。因此,我尋找一些替換線程中的usleep的方法。
個人感覺比較完美的是是用條件信號量。另外用select也行。個人傾向條件信號量,因為條件信號量會掛起線程,不占用cpu,而select實際是輪詢,還是占用cpu的。
下面介紹下條件信號量的要點,具體用法,大家度娘去。
條件信號量分兩種一種是無條件等待(也就是一定要等到信號發過來),一種是我要說的限時等待pthread_cond_timedwait(即超時后自動繼續執行,當然接收到信號也可繼續執行)。
下面具體說下
采用pthread_cond_timedwait(pthread_cond_t* cond, pthread_mutex_t *mutex, const struct timespec *abstime)設置等待條件變量cond,如果超時,則返回;如果等待到條件變量cond,也返回。
當pthread_cond_timedwait()被調用時,調用線程必須已經鎖住了mutex。函數pthread_cond_timedwait()會對mutex進行【解鎖和執行對條件的等待】(原子操作)。這里的原子意味着:解鎖和執行條件的等待是原則的,一體的。(In this case, atomically means with respect to the mutex andthe condition variable and other access by threads to those objectsthrough the pthread condition variable interfaces.)。簡單點說就是必須和mutex一起使用,執行pthread_cond_timedwait()時會阻塞線程等待信號的同時會把muex解鎖。當超時或等到信號,函數返回時,mutex將又會被該線程鎖住。
如果等待條件滿足或超時,或線程被取消,調用線程需要在線程繼續執行前先自動鎖住mutex,如果沒有鎖住mutex,產生EPERM錯誤。即,該函數返回時,mutex已經被調用線程鎖住。
等待的時間通過abstime參數(絕對系統時間,過了該時刻就超時)指定,超時則返回ETIMEDOUT錯誤碼。開始等待后,等待時間不受系統時鍾改變的影響。
盡管時間通過秒和納秒指定,系統時間是毫秒粒度的。需要根據調度和優先級原因,設置的時間長度應該比預想的時間要多或者少點。可以通過使用系統時鍾接口gettimeofday()獲得timeval結構體。