webrtc 多線程一 event

Webrtc 多線程模塊主要涉及 criticalsection、event、messagequeue、thread、messagehandler、physicalsocketserver 等文件. 注意 webrtc 最新的代碼將 base 目錄改為了 rtc_base。

Event

文件路徑 webrtc/base/event.h webrtc/base/event.c.

event.h/event.cc文件中在 namespace rtc 中, 只有class Event類。
該類主要實現了跨平臺的Win32 Event功能。Event類的各個成員函數與Win32 Event所提供的API幾乎一致。

Linux 系統中,WebRTC 使用了mutex和條件變量來實現Event的功能。首先,對Win 32 API和pthread API做一下類比:

  • CreateEvent

pthread_mutex_init、pthread_cond_init這兩個函數用來創建pthread的mute和條件變量。

  • CloseHandle

pthread_mutex_destroy、pthread_cond_destroy這兩個函數用來銷毀pthread的mute和條件變量。

  • SetEvent

pthread_mutex_lock、pthread_mutex_unlock這兩個函數加鎖和解鎖mutex,

pthread_cond_broadcast函數用來解除所有等待在該條件變量上的線程的阻塞狀態。

  • ResetEvent

pthrea_mutex_lock、pthread_mutex_unlock(已解釋)

  • WaitForSingleObject

pthrea_mutex_lock、pthread_mutex_unlock(已解釋)。pthrea_cond_wait函數用來使線程阻塞在條件變量上。

下面將大致解釋一下 Event 類的實現原理:

Event的主要功能由條件變量實現,mutex只是輔助條件變量起到鎖的作用。條件變量的 pthread_cond_wait 和pthread_cond_broadcast函數與Win32 Event的WaitForSingleObject和SetEvent基本類似。Event是否為signal狀態由布爾類型的成員變量event_status_控制。是否為manual reset的Event由布爾類型的成員變量is_manual_reset_控制。與Win32 Event不同的狀況主要體現在Event的manual reset控制上。

linux 系統下所有調用 Event::Wait 函數的線程會阻塞在pthread_cond_wait 函數上。當 Event::Set 函數被調用時,pthread_cond_broadcast 函數會解除所有等待在 pthread_cond_wait 函數上的線程的阻塞狀態。這對于 manual reset 的 Win32 Event 來說沒什么問題,問題出在 auto reset 的 Win32 Event 上。Auto reset 的 Win32 Event 每次只能解除一條等待在Event上的線程的阻塞狀態,其他線程依然為阻塞狀態。這就需要mutex來配合實現了。
在這里要重點解釋一下 pthread_cond_wait 函數的第二個參數 pthread_mutex_t *mutex。當線程進入pthread_cond_wait 函數時會解鎖 mutex,而在離開 pthread_cond_wait 時會重新加鎖 mutex。可以理解為:

intpthread_cond_wait(pthread_cond_t *cond,pthread_mutex_t *mutex)
{
pthread_mutex_unlock(mutex);
…
…
…
pthread_mutex_lock(mutex);
return0;
}

這是 Win32 沒有的行為,需要特別注意。

有了以上的機制后,模擬 auto rest的 Win32 Event 就沒問題了。當第一條線程獲得 mutex 鎖并離開pthread_cond_wait 函數時,其他線程會依然被阻塞在 pthread_mutex_lock(mutex) 函數上,無法離開 pthread_cond_wait 函數。那條成功離開線程會馬上檢測當前的 Event 是否為 manual reset 的,如果不是就馬上將 event_status_ 成員變量設置為 false,并解鎖 mutex。這時其他線程才能有機會離開pthread_cond_wait 函數。不過當他們離開 pthread_cond_wait 后立即檢測 event_status_ 成員變量,如果為 false 就重新調用 pthread_cond_wait 函數。這就完美實現了 Win32 Event 的 auto reset 的語義。

條件變量和 mutex 的配合是 Event 類的難點。如果讀者還是不能完全理解,請仔細閱讀以上 3 段的內容(也可以上網查找 pthread_cond_wait 函數),并結合 event.cc 的源代碼反復揣摩,應該可以很快理解的(畢竟代碼不多,而且也不是WebRTC中真正困難的部分)

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 最近一直在看游雙的《高性能linux服務器編程》一書,下載鏈接: http://download.csdn.net...
    張小方閱讀 1,224評論 0 2
  • 轉自:Youtherhttps://www.cnblogs.com/youtherhome/archive/201...
    njukay閱讀 1,629評論 0 52
  • linux線程同步 信號燈:與互斥鎖和條件變量的主要不同在于"燈"的概念,燈亮則意味著資源可用,燈滅則意味著不可用...
    鮑陳飛閱讀 706評論 0 2
  • 簡介 線程創建 線程屬性設置 線程參數傳遞 線程優先級 線程的數據處理 線程的分離狀態 互斥鎖 信號量 一 線程創...
    第八區閱讀 8,588評論 1 6
  • 摘要 線程概念,線程與進程的區別與聯系學會線程控制,線程創建,線程終止,線程等待了解線程分離與線程安全學會線程同步...
    狼之足跡閱讀 476評論 2 3