webrtc執行緒模型分析
目錄
概述
webrtc是一個跨平臺的實時音訊通訊技術,底層對不同平臺的執行緒介面進行了封裝,本文以windows平臺為例,簡要分析一下其封裝的執行緒類的特點和使用方法。在90版本的webrtc,封裝了三個執行緒相關的類,分別是modules/utility/source/ProcessThreadImpl、rtc_base/TaskQueue、rtc_base/Thread,這三個類建立執行緒都是通過呼叫CreateThread函式來實現,webrtc使用執行緒基本上都是通過這三個類來進行的。
個人感覺webrtc執行緒類的最大特點就是支援線上程間傳遞訊息處理函式,例如執行緒A想讓執行緒B乾點事情,那麼就向執行緒B傳送一個任務,這個任務裡面就包含了需要線上程B內執行的訊息處理函式,這個處理函式往往是lambda函式(當然也可以是全域性的函式)。這種設計最大好處的就是簡化了執行緒間進行通訊的方法,而這又是通過lambda函式的引數捕獲機制來實現的。舉個例子當我們需要向另一個執行緒傳遞多個變數的時候,往往都是通過設計多個引數或者定義一個結構體來實現,在傳遞資料前可能還需要一個個的進行變數賦值,但是通過lambda函式一切就變得簡單了,使用lambda函式的捕獲列表功能,目標執行緒處理訊息時需要什麼引數就可以直接在捕獲列表傳進去,甚至還可以把this指標也給傳進去,然後再在lambda函式內部呼叫類的成員函式。當然了,使用這種執行緒通訊模型需要十分清楚類的成員變數會在哪些執行緒被訪問、那些地方需要加鎖進行保護。
1.ProcessThreadImpl類
ProcessThread執行緒提供的函式是Start、Stop、WakeUp、RegisterModule、DeRegisterModule,可以向執行緒註冊多個處理模組,這些模組會線上程內被頻繁定時呼叫。ProcessThread主要用於建立需要迴圈處理訊息型別的執行緒,例如webrtc中就通過ProcessThread建立了PacerThread、ModuleProcessThread執行緒,其中PacerThread執行緒用於平滑網路資料包的傳送,而ModuleProcessThread用於處理rtp/rtcp訊息等。
2.TaskQueue類
TaskQueue主要提供了PostTask、PostDelayedTask介面。PostTask、PostDelayedTask可以將一個lambda函式作為引數傳入,在lambda函式內部也可以呼叫包含lambda函式的函式,這樣就看下來一個類的成員函式會被不同的執行緒所呼叫,如下面的函式:
void VideoStreamEncoder::OnLossNotification(
const VideoEncoder::LossNotification& loss_notification) {
if (!encoder_queue_.IsCurrent()) {
encoder_queue_.PostTask(
[this, loss_notification] { OnLossNotification(loss_notification); });
return;
}
RTC_DCHECK_RUN_ON(&encoder_queue_);
if (encoder_) {
encoder_->OnLossNotification(loss_notification);
}
}
TaskQueue使用了TaskQueueBase型別的例項。TaskQueue沒有實現不同執行緒間的同步呼叫,PostTask把訊息發到目標執行緒後會立即返回,不會等待目標執行緒處理完訊息,而rtc_base/Thread類的Send/Invoke函式就會等待。
3.Thread類
Thread裡面的Send/Invoke函式可以實現兩個不同執行緒之間的同步呼叫,例如A執行緒呼叫B執行緒的一個函式F,函式F是執行在B執行緒裡面,但是A執行緒在Invoke後會阻塞,等到B執行緒執行完F後A執行緒才繼續往下執行。實現原理是在Invoke內部呼叫了PostTask,在呼叫PostTask時傳入了一個lambda函式,這個lambda函式以引用方式捕獲了一個區域性變數ready,ready在目標執行緒執行完訊息處理函式後會被設定為true,而呼叫者執行緒在PostTask後迴圈等待ready,只有ready等於true後才結束迴圈,從而函式返回,這樣就實現了以同步方式呼叫另一個執行緒的函式。程式碼如下:
bool ready = false;
PostTask(
webrtc::ToQueuedTask([msg]() mutable { msg.phandler->OnMessage(&msg); },
[this, &ready, current_thread] {
CritScope cs(&crit_);
// 執行緒B執行
ready = true;
current_thread->socketserver()->WakeUp();
}));
bool waited = false;
crit_.Enter();
// 執行緒A執行
while (!ready) {
crit_.Leave();
current_thread->socketserver()->Wait(kForever, false);
waited = true;
crit_.Enter();
}
crit_.Leave();
Thread繼承自TaskQueueBase,Thread類主要提供了三個傳送訊息的函式Post、Send、Invoke,其中Post不會阻塞,而Send/Invoke會阻塞,Post/Send可以傳入訊息處理物件,而Invoke可以傳入訊息處理函式(lambda函式)。
全文完。
相關文章
- RxJava 執行緒模型分析RxJava執行緒模型
- netty reactor執行緒模型分析NettyReact執行緒模型
- 執行緒模型執行緒模型
- Redis執行緒模型的原理分析蒼癘Redis執行緒模型
- Dubbo RPC執行緒模型 原始碼分析RPC執行緒模型原始碼
- Hadoop的Server及其執行緒模型分析HadoopServer執行緒模型
- Hadoop 的 Server 及其執行緒模型分析HadoopServer執行緒模型
- Dubbo執行緒模型執行緒模型
- WPF執行緒模型執行緒模型
- redis執行緒模型Redis執行緒模型
- Java、C#執行緒模型分析對比 (轉)JavaC#執行緒模型
- Redis的執行緒模型Redis執行緒模型
- Dubbo的執行緒模型執行緒模型
- 程式和執行緒模型執行緒模型
- 理解 RxJava 執行緒模型RxJava執行緒模型
- Netty執行緒模型Netty執行緒模型
- memcache的執行緒模型執行緒模型
- 03.執行緒模型執行緒模型
- EventBus原始碼分析(四):執行緒模型分析(2.4版本)原始碼執行緒模型
- 聊聊執行緒技術與執行緒實現模型執行緒模型
- 淺談linux執行緒模型和執行緒切換Linux執行緒模型
- 多執行緒之共享模型執行緒模型
- Java 執行緒池執行原理分析Java執行緒
- Netty原始碼分析之Reactor執行緒模型詳解Netty原始碼React執行緒模型
- 執行緒池執行模型原始碼全解析執行緒模型原始碼
- 鴻蒙HarmonyOS實戰-Stage模型(執行緒模型)鴻蒙模型執行緒
- strerror執行緒安全分析Error執行緒
- Redis之單執行緒 Reactor 模型Redis執行緒React模型
- Java 執行緒記憶體模型Java執行緒記憶體模型
- Redis執行緒模型的前世今生Redis執行緒模型
- 【Netty】EventLoop和執行緒模型NettyOOP執行緒模型
- Android的程式,執行緒模型Android執行緒模型
- Muduo 多執行緒模型對比執行緒模型
- 怪異的COM 執行緒模型執行緒模型
- COM套間和執行緒模型.執行緒模型
- 泛說 "COM執行緒模型" (轉)執行緒模型
- (三)Redis 執行緒與IO模型Redis執行緒模型
- Node.js 的單執行緒事件驅動模型和內建的執行緒池模型Node.js執行緒事件模型