當前位置:
首頁 > 知識 > muduo——EventLoop處理線程安全的問題

muduo——EventLoop處理線程安全的問題

為了方便用戶使用定時器介面,增加了幾個函數,這幾個函數都轉而調用TimeQueue::addTimer(),這幾個函數沒有做特別的處理,是允許跨線程使用。

muduo——EventLoop處理線程安全的問題

這樣一來會帶來線程安全性方面的問題,muduo的解決方法不是加鎖,而是把對TimeQueue的操作轉移到IO線程來進行,EventLoop::runInLoop(const Functor& cb)函數,參數cb是回調函數,在它的IO線程執行某個用戶任務回調,如果是在當前IO線程調用這個函數,調用會同步進行,如果用過在其他線程調用runInLoop(),cb會被加入隊列,IO線程會被喚醒來調用Functor。muduo庫中很多處理線程安全問題都是通過這個函數來處理的。

muduo——EventLoop處理線程安全的問題

由於IO線程平時阻塞在時間循環EventLoop::loop()的poll調用中,為了讓IO線程能立即執行用戶回掉,需要設法喚醒它。在libevent中處理信號的時候,用到了socket pair,將一端socket註冊到libevent中管理,在註冊信號函數的時候將它的處理函數自定義為libevent中已經寫好的函數,這個函數中會向socket發消息,這樣就會從阻塞的IO復用中返回。muduo在這裡的處理也差不多使用這一的思路,不過muduo使用的是eventfd(2),可以更高效地喚醒,因為它不需要管理緩衝區。

muduo——EventLoop處理線程安全的問題

wakeup()就是向wakeupFd_中發消息,然後IO復用函數返回之後會調用handleRead()函數來處理, 然後EventLoop::loop()中就會調用doPendingFunctors()函數來處理,這個函數不是簡單調用Functor,而是把回調列表swap()到局部變數functors中,這樣一方面可以減小了臨界區的長度(因為pendingFunctors_是暴露給其他線程的所以需要加鎖,這樣一來就不會阻塞其他線程調用queueInLoop()),另一方面也避免死鎖(因為pendingFunctors_中的Functor可能再調用queueInLoop())。

muduo——EventLoop處理線程安全的問題

喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 程序員小新人學習 的精彩文章:

opencv Mat類型和BYTE*指針類型互轉
PHP 驗證日期格式

TAG:程序員小新人學習 |