5.7.webrtc线程的启动与运行

那在上一节课中呢?我向你介绍了web rtc的三大线程,包括了信令线程,工作线程以及网络线程。那同时呢,我们知道了web rtc 3大线程创建的位置以及运行的时机。

对吧,那么今天呢?我们再继续深入了解一下,看这些线程是如何创建的,以及如何运行的。

那首先呢,我们来看看线程的创建,实际这一页PPT啊,我们在之前已经向你做过介绍了,那我们都知道,对于不同的平台,在创建线程时使用的API都是不一样的,对吧?对于linux以及mac来说呢,它使用的是p three create来创建线程,而对于WINDOWS来说呢?它使用的是create three的来创建线程zur rtc,由于它是支持多平台的。

在这里插入图片描述

所以,对于不同平台的版本,它的代码也是不一样的。那这些呢,我们都需要了解。

今天呢,我们就来详细看一下p three的create以及create three的这两个API。
在这里插入图片描述

它的一些具体参数首先我们来看一下WINDOWS下的create three它都有哪些参数。那我们从这里可以看到啊,对于create three的API来说,它包含的参数还是蛮多的,一共有六项,

那第一项呢,是线程的属性。那一般情况下,这个参数呢?我们都设成了NULL,也就是说采用默认的线程属性,

第二个参数呢?是线程创建好之后使用的堆栈大小,如果我们设置成零,它也是使用默认的堆栈大小。那如果我们对这个堆栈啊,有特殊的要求,你可以在这里进行设置

第三个参数就比较重要了。那它表示的是我们线程启动之后要执行哪个函数,所以这里呢是一个函数地址。

那第四个呢?是参数什么参数呢?就是我们前面设置的这个函数的输入参数。对于这个函数来说呢,它只能有一个输入参数好,

再接下来create flags表示的是创建时设置的一些flag。那通常情况下,我们也设置成零零表示,当线程创建好之后,就立刻参与线程的调度,所以一般情况下呢,我们都将它设成零。

好,最后一个参数,如果我们在创建线程的时候设置了这个参数,那当线程创建好之后就会给我们返回一个线程ID。它呢,其实是一个输出参数,对吧?那下面呢?

我们来看一下web rtc是如何使用create three的这个API的。我们这个例子中所展示这样,那这个呢?就是我从外边tc中拷贝的一段代码,

在这里插入图片描述

那它第一个参数呢?就成了。采用默认的线程属性。第二个参数呢,是零使用默认的堆栈大小。好,第三个参数是pre run。代表要执行哪个函数?第四个呢?是这个函数的输入参数web rtc呢?是将这次传给preturn,第五个参数设成零,就是创建好之后呢,立即参与调度。最后一个参数呢,就是获取我们创建好的线程ID。
在这里插入图片描述

这就是create three的API,那接下来呢,我们再看看linux下的p three的create这个API。对于这个API来说呢,它的参数相对少一些,一共有四项对吧?

那第一项呢是p three的杠t类型的。它表示,当我们创建好线程之后呢,在这个变量中存放一些关于这个线程的基本信息。这是第一个参数,

第二个参数呢?也是线程属性,一般情况下呢,我们只要使用p three的相关的API。给它做一下初始化就OK了,也就是说采用默认的属性。

第三个参数与create three的是类似的,也是一个执行函数。那这个执行函数呢?

也有一个输入参数,也就是第四个参数arg,那这个呢?就是p three的create这个API。
在这里插入图片描述

那我们接着来看一个例子。那对于这个API来说呢,

它的第一个参数是我们创建的p three的杠t类型的一个变量地址,对吧?
那第二个参数呢,是我们创建的的杠attr杠t类型的一个变量地址。
第三个参数是一个执行函数,

最后一个参数呢?一般是我们当前的这个对象,

这就是p three的create API。好,那了解了这两个API之后呢?下面我们再来看看,当我们程序运行起来之后,它的一个基本逻辑是什么?

在这里插入图片描述

其实这一块儿啊,我在前面儿介绍常见的线程模型的时候,我已经向你做过基本的介绍了,其实在执行函数的内部。就是一个外循环,而且是一个死循环,那么在这个循环中,它做什么事儿呢?就做两件事儿,第一件事儿呢,就是从堆列中。取出message消息。当拿到这个消息之后呢,调用dispatch来处理这个消息。(执行函数,拿到消息,让谁处理)

我们再来看看dispatch,在dispatch中它会调用这个消息的handler对象的on message进行逻辑处理。同时,把正在处理的这个消息呢,当做参数。传给内部呢,它就会对这个消息做相应的逻辑处理了,那具体是怎么做的?

每一个消息有不同的逻辑,这就是把控制权交给了发送线程。发送线程在执行逻辑的时候,他是知道他要做什么事的。但是这个事儿呢,他不想自己做,他想交给其他的线程做,

让自己做更重要的事情,对吧?但遇到的一个困难是,执行线程不知道发送线程,它要执行怎样的逻辑?那最好的方法就是让发送线程,把要执行的逻辑写好之后呢,把这个任务交给执行线程,那执行线程 只要按照发送线程的要求。去执行任务就OK了。

这就像我们日常中的管理一样,那对于一个项目管理者来说,你想让你底下的开发人员去帮你完成一个大的项目。由于你对这个项目特别熟悉,所以呢,

你应该把这个项目怎么做?做哪些功能告诉开发人员,这样开发人员按照你的要求把这个代码编写出来就了,对吧?那这也是我们工作中经常采用的一种工作方式,

那实际上在我们的开发项目中啊,你会发现很多的系统的管理都是我们日常生活中的工作方式。只不过说你把日常中的工作方式转换成了代码,让计算机去做这一系列的事,也就是说计算机模拟了我们日常的工作。

那了解了这些内容之后呢?咱们现在切换到Windows系统下来看一下外拔tc的代码是如何实现的?我们把程序运行起来,依然是以peer connection clan的。这个项目为起点,

这样呢,一步一步进入到y八七c的底层。来找到我们创建线程执行线程的地方。好,我们先连接新的服务器,选择我们要连接的对象。这时候呢,首先会创建peer connection factory,对吧?这个在我们之前都介绍过。之后呢,在peer connection factory内部跳到三大线程的创建。网络线程工作线程限定线程对吧?那在这里呢,我们不需要看过多的内容,
在这里插入图片描述
owned_network_thread = rtc::Thread::CreateWitthSocketServer只是创建了一个对象,具体创建什么线程以及线程与对象的绑定都是在start的时候做的

我们只要关注。代码的91行的这个函数,看它内部是如何实现的就了好,我们单步执行。现在呢,跳入到这个函数中OK,这样呢,我们就进入到了的这个函数中,我们来详细看一下,在这个函数中具体做了哪些事情?125行呢,它首先判断现在这个线程是否已经运行了,对吧?如果运行了,我们现在这个逻辑呢,
在这里插入图片描述

就没必要再做了。直接退出就OK了,那显然现在是没有运行的。好,那紧接着呢,它调用了一个restart,这个restart的含义呢,就是将线程的状态机重新复位。那感兴趣的同学呢?可以再跳到这个函数中去看一下具体的事件,这里呢?我们就不详细跟踪了,好,我们继续往下执行。再接下来,

它是创建了一个three的manager实例,对吧?那在这里之所以要执行这条语句呢,是为了确保。street manager已经创建成功了,那在这里的注释呢?也说的非常明显。确保我们在创建一个新线程之前呢?在主线程已经创建了thread manager这个对象。OK,那我们继续走啊。到737行,那这个时候呢,我们就看到了一个非常熟悉的函数,就是create three的。

那通过这个函数呢,我们就将一个线程创建出来了,线程创建成功之后呢,它就会执行这个方法。那下面呢,我们就跳到pre ran,然后来看看在pre ran中做了哪些事情,我们在这里打个断点啊。那当断点来到824行的时候。实际我们的新线程就已经创建成功了,对吧?因为它已经执行到pre ran这个函数中了OK,那下面呢?我们来单步执行一下。在这个函数中呢,
在这里插入图片描述

首先它将传入的参数恢复成。three的对象。之后呢,调用thread manager中的set current three的方法将这个线程呢设置到thread m anager中。那这里啊,我们大家要注意,就是我们创建好的three的对象,什么时候与我们的线程进行绑定的呢?一定是在这个线程已经启动之后才进行绑定的,对吧?这里呢,就是这种情况,就是当我们的线程运行起来,执行了pre ran之后。它才能将当前线程与我们之前创建好的的对象进行绑定,

对吧?其中825行就是做这件事儿了,绝对不可能是我们线程没有创建的。就进行线程的绑定,这是不可能的,这就成了无米之炊了,对吧?OK,那我们再继续往下走,再下来呢,是给这个线程设置一个名字,我们就不看了,之后呢,将three的对象赋值给当前的任务队列。因为本身three的就是一个队列。
在这里插入图片描述

所以就是让我们当前的这个任务队列呢,指向three的也可以这么理解,那执行到831行之后呢,我们就看到。当前线程呢,又拐了一个弯到three的对象的run方法中去执行,我们再跳到这个run方法中。在run方法中呢,它只调用了一个函数,就是process message对吧?我们继续跳进去。那在process message中做了什么事情呢?这块的逻辑啊,就非常简单了,在993行,
在这里插入图片描述

我们就看到了这个while循环。那在这个死循环中,他做了什么事呢?非常简单,首先通过get从消息队列中获取一个消息。之后要用dispatch来处理这个消息,在dispatch中呢,它写了一堆逻辑对吧?但核心的逻辑。就是664行。
在这里插入图片描述

也就是调用p message中的handler对象的on message方法。来对这个消息呢进行处理,具体之中的逻辑只有发送线程才知道,如果我们想知道之中具体做了哪件事儿?(on->message是发送线程的函数,具体要看发送线程怎么搞)

我们就要找发送线程,在构造这个消息的时候。它里边儿的on message具体是如何实验的,我们才能知道里边儿的逻辑是什么,对吧?通过这样一个分析啊,我们可以知道,对于y八七c来说。它各县城的职责其实是非常明确的,每个县城有每个县城要做的事情,每个县城有每个县城的责任。

工作线程我只负责做事儿,对吧?

那信令线程呢?我要与应用层进行交互。

网络线程呢?我负责网络包的收发,这样就使得各线程的工作效率非常的高效。

但同时,它也带来一个问题,就是我们在阅读它代码的时候。就非常的困难,因为当我们进入到工作线程去看它的逻辑的时候,你会发现里边没有什么具体的业务逻辑。

真正的逻辑是在哪儿呢?是在发送线程,有可能是限令线程,有可能是网络线程,他们才知道具体要干什么活儿。

而对于工作线程来说呢,他只是埋头干活儿的人,并不知道具体逻辑是什么,别人让我怎么做,我就怎么做。那这就打破了我们人类思维,从上到下的一个惯性,它实际要跳着来。也就是说,如果我们想知道具体要做哪些事情的时候,你要找到它的根源才能清楚这件事儿到底在做什么,为什么要这样做?

而对于干活的县城来说呢,它是一问三不知。所以这也是我们为什么学习web rtc有这么多困难的一个非常关键的原因,(最主要的一点其实是讲了webrtc的工作线程只是调用了发送线程的接口而已)

好,那通过这节课呢,我们就知道了web rtc的线程是如何创建出来的,以及在线程内部,它是如何运行的。

同时,我们也知道了,我们要想弄清楚各线程之间的逻辑,必须从发送线程着手,而不能从工作线程着手。这样才不至于我们在庞大的代码里迷失方向,

那以上呢,就是我们这节课所介绍内容有任何的问题呢,你可以到讨论区或者是群里去给我留言。我在那里呢,给你做相应解答好,谢谢。

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

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

相关文章

k8s v1.27.4 部署metrics-serverv:0.6.4,kube-prometheus

只有一个问题,原来的httpGet存活、就绪检测一直不通过,于是改为tcpSocket后pod正常。 wget https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml修改后的yaml文件,镜像修改为阿里云 apiVersion: …

窗口函数大揭秘!轻松计算数据累计占比,玩转数据分析的绝佳利器

上一篇文章《如何用窗口函数实现排名计算》中小编为大家介绍了窗口函数在排名计算场景中的应用,但实际上窗口函数除了可以进行单行计算,还可以在每行上打开一个指定大小的计算窗口,这个计算窗口可以由SQL中的语句具体指定,大到整个…

S05-巧用单元格格式转换数据

视频教程 文章目录 S05-巧用单元格格式转换数据 S05-巧用单元格格式转换数据 格式类型默认格式(常规)转换格式数值1.21.200货币1.2¥1.20会计专用1.2¥1.20日期43567四月十二日时间0.3333333338:00 AM百分比1.2120.00%分数0.21/5科…

工作纪实37-mybatis-plus关闭结果集输出log

1.springbootmybatis-pluslogback.xml组合,运行mapper会把sql查询会把结果也打印出来),但是就是不想让它输出到控制台,今天就来记录一下如何操作才能不把sql结果集打印出来,当然sql语句还是会打印的。 2、修改配置 …

响应式编程

响应式编程 响应式编程打破了传统的同步阻塞式编程模型,基于响应式数据流和背压机制实现了异步非阻塞式的网络通信、数据访问和事件驱动架构,能够减轻服务器资源之间的竞争关系,从而提高服务的响应能力。 一、Reactive Stream 要了解什么是响…

从零实战SLAM-第九课(后端优化)

在七月算法报的班,老师讲的蛮好。好记性不如烂笔头,关键内容还是记录一下吧,课程入口,感兴趣的同学可以学习一下。 --------------------------------------------------------------------------------------------------------…

【STM32CubeMX】低功耗模式

前言 本文讲解STM32F10X的低功耗模式,部分资料参考自STM32手册。STM32F10X提供了三种低功耗模式:睡眠模式(Sleep mode)、停机模式(Stop mode)和待机模式(Standby mode)。这些低功耗模…

mysql通过binlog日志恢复误删数据

1、先查看binlog功能是否开启 show variables like %log_bin%;log_bin为ON说明可以使用binlog恢复,如果为OFF说明没有开启binlog。 2、删除部分数据做测试 3、查找binlog文件位置 show variables like %datadir%;cd /var/lib/mysqlls -l删除数据时间是在文件154与…

7个改变玩法规则的ChatGPT应用场景

ChatGPT因各种原因受到了广泛关注:ChatGPT可以充当各种改善生活改进工作的小助手,如内容写手、客户支持、语言翻译、编码专家等等。只需在你的聊天内容中添加适当的提示,人工智能将为你提供各项支持。[1] 1.ChatGPT作为内容写手 通过AI的帮助…

有生日视频模板软件吗?分享一个模板丰富的视频软件

视频制作可以让你制作出一个生动、吸引人的生日视频,让你的生日祝福更加具有创意和个性化。通过使用生日模板视频,你可以省去很多制作视频的时间和精力,同时还可以获得高品质的视频输出。此外,生日模板视频通常具有专业的风格和设…

视频云存储/安防监控EasyCVR视频汇聚平台如何通过角色权限自行分配功能模块?

视频云存储/安防监控EasyCVR视频汇聚平台基于云边端智能协同,支持海量视频的轻量化接入与汇聚、转码与处理、全网智能分发、视频集中存储等。音视频流媒体视频平台EasyCVR拓展性强,视频能力丰富,具体可实现视频监控直播、视频轮播、视频录像、…

永久设置pip指定国内镜像源(windows内)

1.首先列出国内四个镜像源网站: 一、清华源 https://pypi.tuna.tsinghua.edu.cn/simple/ 二、阿里源 https://mirrors.aliyun.com/pypi/simple 三、中科大源 https://pypi.mirrors.ustc.edu.cn/simple/ 四、豆瓣源 http://pypi.douban.com/simple/ 2.一般下载所需要…

Android Studio run app 设置 release 模式

背景 为验证我们的 SDK 集成在客户应用上的质量,需要我们的测试环境尽量的与客户应用保持一致。客户普遍都会打 release 包并混淆,然后进行上线应用,因此我们在测试过程中也需要使用 release 包进行验证。对于 Android Studio 运行项目&…

从Web 2.0到Web 3.0,互联网有哪些变革?

文章目录 Web 2.0时代:用户参与和社交互动Web 3.0时代:语义化和智能化影响和展望 🎉欢迎来到Java学习路线专栏~从Web 2.0到Web 3.0,互联网有哪些变革? ☆* o(≧▽≦)o *☆嗨~我是IT陈寒🍹✨博客主页&#x…

变频器和plc之间无线MODBUS通讯

在工业现场由PLC远程控制变频器的应用非常常见,如果挖沟布线不便或者变频器在移动设备上,那么采用无线通讯就是最佳方案。 这里我们选用最常用的三菱 FX2N PLC和三菱变频器为例,并结合日系plc专用无线通讯终端DTD435M来说明PLC与变频器之间的…

触摸屏与PLC之间 EtherNet/IP无线以太网通信

在实际系统中,同一个车间里分布多台PLC,用触摸屏集中控制。通常所有设备距离在几十米到上百米不等。在有通讯需求的时候,如果布线的话,工程量较大耽误工期,这种情况下比较适合采用无线通信方式。 本方案以MCGS触摸屏和…

Python爬虫实战案例——第一例

X卢小说登录(包括验证码处理) 地址:aHR0cHM6Ly91LmZhbG9vLmNvbS9yZWdpc3QvbG9naW4uYXNweA 打开页面直接进行分析 任意输入用户名密码及验证码之后可以看到抓到的包中传输的数据明显需要的是txtPwd进行加密分析。按ctrlshiftf进行搜索。 定位来到源代码中断点进行调…

Android2:构建交互式应用

一。创建项目 项目名Beer Adviser 二。更新布局 activity_main.xml <?xml version"1.0" encoding"utf-8"?><LinearLayout xmlns:android"http://schemas.android.com/apk/res/android"android:layout_width"match_parent"…

【C++】做一个飞机空战小游戏(十一)——游戏过关、通关、结束的设置

[导读]本系列博文内容链接如下&#xff1a; 【C】做一个飞机空战小游戏(一)——使用getch()函数获得键盘码值 【C】做一个飞机空战小游戏(二)——利用getch()函数实现键盘控制单个字符移动【C】做一个飞机空战小游戏(三)——getch()函数控制任意造型飞机图标移动 【C】做一个飞…

接口测试 —— Jmeter 参数加密实现

Jmeter有两种方法可以实现算法加密 1、使用__digest自带函数 参数说明&#xff1a; Digest algorithm&#xff1a;算法摘要&#xff0c;可输入值&#xff1a;MD2、MD5、SHA-1、SHA-224、SHA-256、SHA-384、SHA-512 String to be hashed&#xff1a;要加密的数据 Salt to be…