WebRTC源碼線程-1

1、概述

本篇主要是簡單介紹WebRTC中的線程,WebRTC源碼對線程做了很多的封裝。

1.1 WebRTC中線程的種類

1.1.1 信令線程

用于與應用層的交互,比如創建offer,answer,candidate等絕大多數的操作

1.1.2 工作線程

負責內部的處理邏輯,比如音視頻編解碼、采集、渲染這些操作,平滑處理,質量監測

1.1.3 網絡線程

負責網絡數據包的轉發,工作線程對音視頻數據進行編碼后,發送編碼后的音視頻數據到網絡。

從網絡中接收音視頻數據包,然后交給工作線程進行解碼,丟包處理等操作

1.2 peerconnection_client

peerconnection_client一共創建了5個線程,分別為

主線程:windows中main函數的,處理窗口消息的線程

與信令服務器連接處理的線程:PhysicalSocketServer關聯

信令線程:PhysicalSocketServer關聯

工作線程:NullSocketServer關聯

網絡線程:PhysicalSocketServer關聯

1.3?線程類關系圖

1.4 線程類

class RTC_LOCKABLE RTC_EXPORT Thread : public TaskQueueBase {public:explicit Thread(SocketServer* ss);SocketServer* socketserver();bool Start();virtual void Stop();virtual void Run();bool ProcessMessages(int cms);protected:void PostTaskImpl(absl::AnyInvocable<void() &&> task,const PostTaskTraits& traits,const Location& location) override;private:absl::AnyInvocable<void() &&> Get(int cmsWait);void Dispatch(absl::AnyInvocable<void() &&> task);#if defined(WEBRTC_WIN)static DWORD WINAPI PreRun(LPVOID context);
#elsestatic void* PreRun(void* pv);
#endifstd::queue<absl::AnyInvocable<void() &&>> messages_ RTC_GUARDED_BY(mutex_);std::priority_queue<DelayedMessage> delayed_messages_ RTC_GUARDED_BY(mutex_);SocketServer* const ss_;
#if defined(WEBRTC_POSIX)pthread_t thread_ = 0;
#endif
#if defined(WEBRTC_WIN)HANDLE thread_ = nullptr;DWORD thread_id_ = 0;
#endif
};
  • 成員變量 thread_ 在不同平臺有不同的實現,win下采用線程內核對象創建,linux下采用pthread創建
  • 成員變量 messages_ 相當于里面保存的是函數對象,只不過用absl庫,我們可以把它當做是std::function函數對象
  • 線程之間通信,通過PostTask函數進行,相當于線程1需要執行的任務放入線程2的queue,然后線程2不斷從queue讀取任務執行,這樣來進行通信

1.5 線程管理類?

class RTC_EXPORT ThreadManager {public:static ThreadManager* Instance();static void Add(Thread* message_queue);static void Remove(Thread* message_queue);Thread* CurrentThread();void SetCurrentThread(Thread* thread);private:// This list contains all live Threads.std::vector<Thread*> message_queues_ RTC_GUARDED_BY(crit_);#if defined(WEBRTC_POSIX)pthread_key_t key_;
#endif#if defined(WEBRTC_WIN)const DWORD key_;
#endif
};

線程管理類ThreadManager用到一個技術點是線程本地存儲(TLS),需要理解這個技術點,否則比較難讀懂WebRTC源碼中線程這塊的代碼。

1.5.1 線程本地化存儲(TLS)

#include <windows.h>
#include <stdio.h>// 全局 TLS 索引
DWORD tlsIndex;// 線程函數
DWORD WINAPI ThreadFunction(LPVOID lpParam) {int threadNum = *(int*)lpParam;char buffer[256];// 為當前線程設置 TLS 值sprintf_s(buffer, "線程 %d 的私有數據", threadNum);TlsSetValue(tlsIndex, strdup(buffer));  // 注意:使用 strdup 分配內存// 獲取并打印當前線程ID和TLS值DWORD threadId = GetCurrentThreadId();char* data = (char*)TlsGetValue(tlsIndex);printf("線程 ID=%lu, 編號=%d, TLS 數據: %s\n", threadId, threadNum, data);// 清理分配的內存free(data);return 0;
}int main() {// 分配 TLS 索引tlsIndex = TlsAlloc();if (tlsIndex == TLS_OUT_OF_INDEXES) {printf("TlsAlloc 失敗,錯誤碼: %d\n", GetLastError());return 1;}// 在主線程中設置并獲取 TLS 值char mainBuffer[256];sprintf_s(mainBuffer, "主線程的私有數據");TlsSetValue(tlsIndex, strdup(mainBuffer));// 打印主線程ID和TLS值DWORD mainThreadId = GetCurrentThreadId();char* mainData = (char*)TlsGetValue(tlsIndex);printf("主線程 ID=%lu, TLS 數據: %s\n", mainThreadId, mainData);// 創建兩個線程int thread1Num = 1;int thread2Num = 2;HANDLE hThread1 = CreateThread(NULL, 0, ThreadFunction, &thread1Num, 0, NULL);HANDLE hThread2 = CreateThread(NULL, 0, ThreadFunction, &thread2Num, 0, NULL);// 等待線程結束WaitForSingleObject(hThread1, INFINITE);WaitForSingleObject(hThread2, INFINITE);// 關閉線程句柄CloseHandle(hThread1);CloseHandle(hThread2);// 清理主線程分配的內存free(TlsGetValue(tlsIndex));// 釋放 TLS 索引TlsFree(tlsIndex);return 0;
}

在每個線程中保存的value不一樣,每個線程取出來的value就是不一樣,通俗地說,假設我們有3個線程,分別為Thread1、Thread2、Thread3, 分別保存value為1、2、3,那么如果當前如果在Thread2運行的代碼里面打印value,那么打印的就是2。通過這樣的原理,假如當前是信令線程,通過ThreadManager的函數CurrentThread那么返回的就是信令線程,如果需要在網絡線程中運行,則需要利用PostTask放入到網絡線程中使用,我們可以看到WebRTC源碼很多都是用這個來進行判斷。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/908999.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/908999.shtml
英文地址,請注明出處:http://en.pswp.cn/news/908999.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

spring:使用標簽xml靜態工廠方法獲取bean

在spring可以直接通過配置文件獲取bean對象&#xff0c;如果獲取的bean對象還有若干設置&#xff0c;需要自動完成&#xff0c;可以通過工廠方法獲取bean對象。 靜態工廠類&#xff0c;其中InterfaceUserDao和InterfaceUserService都是自定義的接口&#xff0c;可以自己替換。…

linux 用戶態時間性能優化工具perf/strace/gdb/varlind/gprof

1. perf top -g或者top分析卡頓(cpu占用比較高的函數) gdb 是 GNU 調試器,可以用于分析程序的時間性能。雖然 info time 不是直接用于性能分析的命令,但 gdb 提供了與時間相關的功能,例如通過 timer 命令設置計時器或通過 info proc 查看進程的時間信息。 #include <…

客戶端和服務器已成功建立 TCP 連接【輸出解析】

文章目錄 圖片**1. 連接狀態解析****第一條記錄&#xff08;服務器監聽&#xff09;****第二條記錄&#xff08;客戶端 → 服務器&#xff09;****第三條記錄&#xff08;服務器 → 客戶端&#xff09;** **2. 關鍵概念澄清****(1) 0.0.0.0 的含義****(2) 端口號的分配規則** *…

Win系統下的Linux系統——WSL 使用手冊

我們在復現一些項目的時候&#xff0c;有些依賴包只能在 linux 環境下使用&#xff0c;還不打算使用遠程服務器&#xff0c;那么此時我們可以使用 WSL 創建一個 ubutu 系統&#xff0c;在這個系統里創建虛擬環境、下載依賴包。然后&#xff0c;我們就可以在 windows 下的 vscod…

電腦同時連接內網和外網的方法,附外網連接局域網的操作設置

對于工作一般都設置在內網網段中&#xff0c;而同時由于需求需要連接外網&#xff0c;一般只能通過內網和外網的不斷切換進行設置&#xff0c;如果可以同時連接內網和外網會更加便利&#xff0c;同時連接內網和外網方法具體如下。 一、電腦怎么弄可以同時連接內網和外網&#…

C++11:原子操作與內存順序:從理論到實踐的無鎖并發實現

文章目錄 0.簡介1.并發編程需要保證的特性2.原子操作2.1 原子操作的特性 3.內存順序3.1 順序一致性3.2 釋放-獲取&#xff08;Release-Acquire)3.3 寬松順序&#xff08;Relaxed)3.4 內存順序 4.無鎖并發5. 使用建議 0.簡介 在并發編程中&#xff0c;原子性、可見性和有序性是…

oracle 歸檔日志與RECOVERY_FILE_DEST 視圖

1. RECOVERY_FILE_DEST 視圖的作用 RECOVERY_FILE_DEST 是 Oracle 數據庫用于 管理快速恢復區&#xff08;Fast Recovery Area, FRA&#xff09; 的一個視圖。FRA 是 Oracle 提供的一種集中存儲恢復相關文件&#xff08;如歸檔日志、備份文件、閃回日志等&#xff09;的區域。…

零基礎玩轉物聯網-串口轉以太網模塊如何快速實現與MQTT服務器通信

目錄 1 前言 2 環境搭建 2.1 硬件準備 2.2 軟件準備 2.3 驅動檢查 3 MQTT服務器通信配置與交互 3.1 硬件連接 3.2 開啟MQTT服務器 3.3 打開配置工具讀取基本信息 3.4 填寫連接參數進行連接 3.5 通信測試 4 總結 1 前言 MQTT&#xff1a;全稱為消息隊列遙測傳輸協議&#xff08;…

六、Sqoop 導出

作者&#xff1a;IvanCodes 日期&#xff1a;2025年6月7日 專欄&#xff1a;Sqoop教程 Apache Sqoop 不僅擅長從關系型數據庫 (RDBMS) 向 Hadoop (HDFS, Hive, HBase) 導入數據&#xff0c;同樣也強大地支持反向操作——將存儲在 Hadoop 中的數據導出 (Export) 回關系型數據庫。…

數據結構-如果將堆結構應用到TOP-K問題上會怎樣?

數據結構的應用-如何用堆解決TOP-K問題 前言一、TOP-K問題是什么&#xff1f;二、如何用堆解決TOP-K問題1.怎么建堆&#xff0c;建大堆還是小堆&#xff1f;2.代碼實現 總結 前言 本篇文章進行如何用堆結構解決TOP-K問題的講解 一、TOP-K問題是什么&#xff1f; TOP-k問題&am…

Elasticsearch的索引

正向索引和倒排索引 什么是正向索引&#xff1f; 傳統的數據庫采用正向索引&#xff0c;如MySQL將表中的id創建索引&#xff0c;正向索引在進行不是id為索引進行搜索的時候&#xff0c;會逐條進行查詢&#xff0c;比方說 上圖的表格&#xff0c;數據庫進行逐條查詢&#xff0c;…

分散電站,集中掌控,安科瑞光伏云平臺助力企業綠色轉型

本項目位于香港全境共計52個分布式光伏站&#xff0c;總裝機容量8.6MW。發電模式自發自用&#xff0c;余電上網&#xff0c;逆變器采用陽光電源SG100CX、SG20RT等12種型號共計103臺&#xff0c;其余型號共計15臺。每個站點均配置氣象站。 項目采用AcrelCloud-1200分布式光伏運…

開發記錄:修復一些Bug,并實現兩個功能

開發記錄&#xff1a; &#x1f4cb; 工作概述 到今天主要完成了AI閱讀助手的兩大核心功能&#xff1a;前情提要和名詞解釋&#xff0c;并對相關交互體驗進行了優化。通過流式SSE技術實現了實時AI內容生成&#xff0c;大幅提升了用戶體驗。 &#x1f3af; 主要完成功能 1…

LLM基礎1_語言模型如何處理文本

基于GitHub項目&#xff1a;https://github.com/datawhalechina/llms-from-scratch-cn 工具介紹 tiktoken&#xff1a;OpenAI開發的專業"分詞器" torch&#xff1a;Facebook開發的強力計算引擎&#xff0c;相當于超級計算器 理解詞嵌入&#xff1a;給詞語畫"…

【HarmonyOS 5.0】開發實戰:從UI到Native全解析

一、環境搭建與項目創建 ??跨平臺安裝?? DevEco Studio支持Windows/macOS系統&#xff0c;安裝包集成HarmonyOS SDK、Node.js和OHPM工具鏈。 Windows&#xff1a;雙擊.exe選擇非中文路徑macOS&#xff1a;拖拽.app至Applications目錄驗證&#xff1a;通過Help > Diagnos…

零知開源——STM32F103RBT6驅動 ICM20948 九軸傳感器及 vofa + 上位機可視化教程

STM32F1 本教程使用零知標準板&#xff08;STM32F103RBT6&#xff09;通過I2C驅動ICM20948九軸傳感器&#xff0c;實現姿態解算&#xff0c;并通過串口將數據實時發送至VOFA上位機進行3D可視化。代碼基于開源庫修改優化&#xff0c;適合嵌入式及物聯網開發者。在基礎驅動上新增…

華為OD最新機試真題-食堂供餐-OD統一考試(B卷)

題目描述 某公司員工食堂以盒飯方式供餐。 為將員工取餐排隊時間降低為0,食堂的供餐速度必須要足夠快,現在需要根據以往員工取餐的統計信息,計算出一個剛好能達成排隊時間為0的最低供餐速度。即,食堂在每個單位時間內必須至少做出 多少價盒飯才能滿足要求。 輸入描述 第1行…

【筆記】MSYS2 的 MINGW64 環境 全面工具鏈

#工作記錄 MSYS2 的 MINGW64 環境&#xff08;mingw64.exe&#xff09;&#xff0c;下面是為該環境準備的最全工具鏈安裝命令&#xff08;包括 C/C、Python、pip/wheel、GTK3/GTK4、PyGObject、Cairo、SDL2 等&#xff09;。 這一環境適用于構建原生 64 位 Windows 應用程序。…

基于 HTTP 的單向流式通信協議SSE詳解

SSE&#xff08;Server-Sent Events&#xff09;詳解 &#x1f9e0; 什么是 SSE&#xff1f; SSE&#xff08;Server-Sent Events&#xff09; 是 HTML5 標準中定義的一種通信機制&#xff0c;它允許服務器主動將事件推送給客戶端&#xff08;瀏覽器&#xff09;。與傳統的 H…

【react+antd+vite】優雅的引入svg和阿里巴巴圖標

1.安裝相關包 由于是vite項目&#xff0c;要安裝插件來幫助svg文件引入進來&#xff0c;否則會失敗 npm下載包 npm i vite-plugin-svgr vite.config.ts文件內&#xff1a; import svgr from "vite-plugin-svgr"; //... export default defineConfig({plugins: …