sleep/usleep和多執行緒鎖的注意事項
阿新 • • 發佈:2019-02-02
最近在寫一個OJ後臺程式,一個主執行緒隔500毫秒讀取一次資料庫把任務放入佇列中,起了4個執行緒用於處理任務(主要是得到任務,然後去資料庫裡讀提交上來的程式碼).
主執行緒
while(true){
pthrea_lock_mutex(&conn_mutex);//資料庫連線的mutex
//..讀資料庫..把任務放入佇列中..
usleep(500000);
pthread_unlock_mutex(&conn_mutex);
}
子執行緒
while(true){ //得到一個任務 //去資料庫裡讀出提交的程式碼 pthread_mutex_lock(&conn_mutex);//阻塞在這裡 //讀程式碼 pthread_mutex_unlock(&conn_mutex); }
發現如果把pthread_mutex_unlock放在usleep()函式後面的話,其他4個執行緒就一直阻塞在lock上.
查了下資料,原來當這個執行緒從usleep()醒來後,unlock掉mutex之後,執行緒排程程式並不會立即讓其他執行緒去佔有這個mutex,由於當前執行緒剛從還有剩餘時間片,於是又得到了這個mutex,而其他的執行緒就沒有機會得到這個mutex.
解決方法就是把usleep(500000)和pthread_unlock_mutex(&conn_mutex)換個位置
結論:不要持有一個mutex太久,特別是不能在sleep()的時候持有一個mutexwhile(true){ pthrea_lock_mutex(&conn_mutex);//資料庫連線的mutex //..讀資料庫放入佇列中.. pthread_unlock_mutex(&conn_mutex); usleep(500000); }