5.5.webrtc的线程管理

今天呢,我们来介绍一下线程的管理与绑定,首先我们来看一下web rtc中的线程管理类,也就是thread manager。对于这个类来说呢,其实实现非常简单,对吧?

包括了几个重要的成员,第一个成员呢就是instance成员,通过这个名字,我们也可以知道它属于单例模式。那通过instance呢,我们就可以拿到thread manager这个对象了,

对吧?这是第一个thread manager的第二个成员呢,是message。通过它的类型啊,我们可以知道这个呢,就是存放所有y8 rtc中的线程对象的,那它是一个victor,也就是一个数组。在这个数组中呢,可以存放three的类型的指针。

再接下来呢,是一个临界区。security section对于message里边的所有线程的操作读啊取啊都要对它先进行加锁,那只有获得锁之后呢才能操作这个队列。

在这里插入图片描述

再接下来这个k呢也十分关键,它属于three的local storage的内容,关于这部分知识呢,一会儿我会向你做详细介绍。那我们现在再来看three的manager这个类,那它有一个最主要的成员就是message,除此之外呢,还有一个k那这个k呢,现在大家还不知道什么意思,那一会儿呢,我就会讲到。

那我们来看看thread manager,它是如何管理线程的?实际上,对于thread manager来说呢,它有两个队列,第一个队列就是我们刚才介绍的message q。在它里边儿呢,可以存放很多的线程对象,那除了这个message之外呢,

还有一个k。那这个k是什么作用呢?就是three的local storage,也就是专门用于本地线程存储的。那你可以把它想象成是一个map表,对吧?它的k呢?就是一个线程ID值呢?
在这里插入图片描述

可以是任意对形的对象。那对于外边rtc来说呢,它里边存放的就是three的指针,这个map与three的manager中的message q每一项呢都是一一对应的,也就是说第一项的three的对应这里的。tid thread第二项呢?对应第二项

就是一一对应这张图对于我们理解thread manager来说是非常关键的。如果我们对这个结构不清楚的话,你就很难理解thread manager它里边的逻辑为什么要那么实现?只有我们把这个图搞清楚了之后,我们才能理解它里边的逻辑,那除此之外呢,

对于message crease中的。每个three的对象都是由构造three的时创建的,而对于k中的每一项呢,是在线程执行的时候。通过set current three的来设置的,那现在呢我们只需要记住这两点就OK了,

第一点呢就是我们message query中的每一个three的。它是在线程的构造函数中创建的,属于three的local story中的内容呢?

是在当前线程执行的时候。调用来设置的那下面呢?我们来具体介绍一下three的local storage。那关于three的local storage呢,应该是在C加加幺幺引入的对,所以它引入的时间呢,并不是很长,下面呢,我们来看看three的local storage,它的一些基本用法。
在这里插入图片描述

第一个呢,就是tls I lock,那tls呢,就是thread local storage的缩写。I lock就是分配的意思,那对于这个函数来说呢?它返回的是一个全局的索引值。当然,在底层的内存中呢,实际就分配一个map,有k有value okay,那这里返回的这个索引值是什么意思呢?实际上,对于我们系统中的每一个进程来说,它都有一个唯一的索引值,

也就说每一个进程一块空间。在这个空间中呢,它里边是一个map表,而为了索引到这个空间,它有一个索引值。比如我一号进程,它的索引值可能是一二号进程,它的索引值可能是二,以此类推就是大概这个意思。总之呢,它是通过索引值来找到这块内存空间的,这个呢,就是tls I这个函数的作用。好,那有了这个空间之后呢,

我们就可以用tls set value来向I lock分配的这个空间里边插入值。插入的内容呢,就是tid和date,当然我们存放的时候对于tls set value来说,你应该输入两个参数。第一个参数呢就是tls I lock返回的这个索引值,那第二个值呢就是我们要存入的数据。

而在内存中呢,它真正存放的是tid和data,那它是怎么找到的呢?实际上就是根据你传入的这个索引值,也就是tls I lock。产生的这个索引值找到内存中的这个map之后呢,再获取你当前线程的线程ID。之后把线程ID当做k你存入的data为value,
在这里插入图片描述

这样呢,将这个k value对儿插入到map中就是这样一个简单的过程。那它提供的第三个就是get value,也就是说从内存中通过当前线程ID获取到我们之前存储的值。它主要呢就是这三个函数对于web rtc,它在使用的时候呢,也是一直用的这三个函数,

那接下来呢,我们来看一个实例,就是来查看一下peer connection c。demo程序中的主线程与three的线程是如何绑定的?我们切换到Windows系统下。OK好,我们还是打开peer connection clan的这个项目之后呢,找到men点CC这个文件,
在这里插入图片描述

那在这里边呢,我们找到。文本中的第81行也就是这一句。通过这行语句呢,实际就实现了。主线程与前面我们创建的win四二three的对象的绑定,现在我们应该清楚上节课我们介绍的win四二three的对象。实际它就是一个线程对象,并不是一个真正的线程,而对于我们peer connection clan端来说呢,它现在的主线程已经启动起来了。那如何将主线程与我们前面创建的对象绑定起来?秘密就在于set current three的这个函数。那下面呢,我们就跳到这个函数中看一下它是如何实现的。
在这里插入图片描述

好,那在three的manager的set current three的方法中呢?实际就调用了set current three的internal。这个方法对吧?我们继续跳进去。那在这个函数中呢,我们看到只有一条语句,就是tls set value。这个k呢,就是我们刚才介绍的这个索引值,它是通过tls I lock分配的。
在这里插入图片描述
对于sweet manager来说,这个k是什么时候产生的呢?实际就是在它的构造函数,我们看一下281行。

它的构造函数中呢,调用了tls I lock方法,最终获得我们本地线程的存储空间。并将索引值呢复制给k。
在这里插入图片描述

那么,在调用set current three的internal方法的时候呢,就可以直接将我们之前创建的three的对象指针。当做参数设置到k所指定的内存空间中,那这样呢,我们就看到了两个方法的使用,那第一个呢是线程本地空间的分配。第二个呢,是向线程本地空间存储,我们自己的数据。那由于我们现在是在主线程内执行的,

所以呢,对于存储到内存中的值一定是我们当前线程的线程ID与我们要存入的线程对象的指针。形成了一个ky 6对儿,存放到了内存空间中,对吧?好,那通过这种方式呢,就实现了当前线程与three的对象之间的绑定。
在这里插入图片描述

其实还是非常好理解的,对吧OK那了解了当前线程与three的对象的绑定,那下面呢,我们再来看看three的对象是什么时候插入到three的many中中的。那这个时候呢,我们就要看一下win 3 r t hree的这个类的实现了。那我们跳到这个类中win三二three的类是继承自three的类的好,
在这里插入图片描述

我们继续跳到three的类的实现。那在这里边儿呢,比较关键的一点是它的构造函数对吧?我们要弄清three的对象,创建好之后是什么时候插入到three的manager中的?必须要看一下它的构造函数的视线。我们跳到它的构造函数中,对于three的对象的构造函数呢?上节课已经向你介绍过它有多种空载。包括了socket server指针,智能指针,智能指针加do I it,对吧?那通过这个代码,我们可以发现啊,

实际所有的构造函数,最终呢,都会调用。这个构造函数我们来看一下,在这个构造函数中,它做了哪些事情?
在这里插入图片描述
其中比较关键的一点就是调了。我们进入到doin it那,在这个函数中做了什么事儿呢?我们看一下372行,那在这里呢?执行了一条语句,就是将。这次指针插入到three的manager中,我们可以继续往下跳,
在这里插入图片描述

找到add,再找到add internal。在add internal函数中的129行,我们就可以看到它。
在这里插入图片描述
最终呢,将message query加入到了。message query中,而message query就是一个three的对象指针对吧?这样呢,我们就将整个的逻辑搞清楚了,再切回到WI MI函数的80行和81行。通过这两条语句呢,我们就可以知道在80行是创建了一个win三二three的,在创建好之后就被插入到three的manager中了。对吧,

之后呢,他又调用了set current three的这个方法,将当前线程与我们刚才创建的win cr three的对象。进行了绑定,那这样呢,就使得当前线程与three的对象产生了一对一的关系。(队列和对象绑定,对象和线程绑定,队列和线程绑定)

那之后呢,我们就可以利用win 12 three的对象中的队列进行消息处理了。那以上呢,就是web rtc three的对象与线程进行绑定的一个过程,那经过刚才我们代码的分析呢,我们现在已经知道web rtc。线程与线程对象之间是如何进行绑定的?是如何进行管理的了?对吧?

其中的核心点呢?就是这张图。如果你对这张图非常熟悉的话,那就知道它的逻辑其实非常的简单,如果这张图你不了解的话,不知道还有three的local storage。这个map表儿的话,你就很难理解y8 rtc线程是如何管理的,那有些看了我书的同学呢,就对这一块儿逻辑不太清楚,像我提出了很多问题。根本的原因呢,就在于我书中没有对这块儿知识做详细介绍,所以他们无法理解,那现在呢,
在这里插入图片描述

大家了解了这块儿知识之后呢,应该对外边儿tc的street manager。它是如何管理线程的?线程与对象之间是如何绑定的?就非常清楚了,那后边呢?我们再看后续的代码的时候。就非常容易了好,那今天呢?我们的课就到这里,有任何的问题呢,你可以到讨论区或者是群里去给我留言,我在那里呢,给你做相应的解答好,谢谢。

回播放处

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/76060.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

拥塞控制(TCP限制窗口大小的机制)

拥塞控制机制可以使滑动窗口在保证可靠性的前提下,提高传输效率 关于滑动窗口的属性以及部分机制推荐看TCP中窗口和滑动窗口的含义以及流量控制 拥塞控制出现的原因 看了上面推荐的博客我们已经知道了,由于接收方接收数据的能力有限,所以要通…

【机器学习 | 分类指标大全】全面解析分类评估指标:从准确率到AUC,多分类问题也不在话下, 确定不来看看?

🤵‍♂️ 个人主页: AI_magician 📡主页地址: 作者简介:CSDN内容合伙人,全栈领域优质创作者。 👨‍💻景愿:旨在于能和更多的热爱计算机的伙伴一起成长!!&…

自动驾驶合成数据科普一:不做真实数据的“颠覆者”,做“杠杆”

前言: 在7月底的一篇文章中,九章智驾提到,数据闭环能力是自动驾驶下半场的“入场券”,这一观点在行业内引起了广泛共鸣。 在数据闭环体系中,仿真技术无疑是非常关键的一环。仿真的起点是数据,而数据又分为真…

使用SpringBoot + Thymeleaf 完成简单的用户登录

😀前言 本篇博文是关于Thymeleaf 的综合案例, 使用SpringBoot Thymeleaf 完成简单的用户登录-列表功能,希望你能够喜欢😊 🏠个人主页:晨犀主页 🧑个人简介:大家好,我是晨…

一文彻底理解时间复杂度和空间复杂度(附实例)

目录 1 PNP?2 时间复杂度2.1 常数阶复杂度2.2 对数阶复杂度2.3 线性阶复杂度2.4 平方阶复杂度2.5 指数阶复杂度2.6 总结 3 空间复杂度 1 PNP? P类问题(Polynomial)指在多项式时间内能求解的问题;NP类问题(Non-Deterministic Polynomial)指在…

自动驾驶——车辆动力学模型

/*lat_controller.cpp*/ namespace apollo { namespace control {using apollo::common::ErrorCode;//故障码 using apollo::common::Status;//状态码 using apollo::common::TrajectoryPoint;//轨迹点 using apollo::common::VehicleStateProvider;//车辆状态信息 using Matri…

录屏有哪些讲究?有哪些好用的录屏软件?

在如今数字时代,视频分享已经成为一种流行的传播方式。为了制作高质量的视频内容,录屏已经成为了一种必备的技能。但是,要想制作出令人满意的录屏视频,需要了解一些讲究和使用一些好用的录屏软件。 录屏是一种视觉传达方式&#x…

QT:绘图事件QPainter

绘图事件QPainter 绘图事件&#xff08;需要重写的函数&#xff09;&#xff1a;paintEvent 声明一个画家对象 QPainter painter(this) 指定绘图设备 画线&#xff0c;画圆&#xff0c;画矩形&#xff0c;画文字 可设置画笔&#xff0c;画刷#include <QPainter> ...... …

Three.js 实现模型材质局部辉光效果和解决辉光影响场景背景图显示的问题

1.Three.js 实现模型材质局部辉光效果 2.解决辉光效果影响场景背景图显示的问题 相关API的使用&#xff1a; 1. EffectComposer&#xff08;渲染后处理的通用框架&#xff0c;用于将多个渲染通道&#xff08;pass&#xff09;组合在一起创建特定的视觉效果&#xff09; 2. …

实例040 限制窗体大小

实例说明 Windows窗体是可以随意改变大小的&#xff0c;然而对于一些要求严格的窗体&#xff0c;开发人员不希望用户随意的改变其大小&#xff0c;例如&#xff0c;定位准确的地图和游戏软件等。遇到这种情况必须对窗口的大小进行一些限制。本例设计一个限制了大小的窗体&#…

vueuse常用方法

useDateFormat 时间格式化 <script setup lang"ts">import { useNow, useDateFormat } from vueuse/coreconst formatted useDateFormat(useNow(), YYYY-MM-DD HH:mm:ss)</script><template><div>{{ formatted }}</div> </templa…

Delphi 安卓App自动升级

Androidapi.JNI.Support引用这个单元 procedure _InstallApk(Apk: string); varLFile: JFile;LIntent: JIntent; beginLFile : TJFile.JavaClass.init(StringToJString(ExtractFilePath(Apk)), StringToJstring(ExtractFileName(Apk)));LIntent : TJIntent.Create;LIntent.set…