5.9.Webrtc线程事件处理

在前面的课程中呢,我已经向你介绍了事件处理的一些基础知识,那今天呢,我们再来看一下外边儿rtc下事件处理的基本逻辑是什么?
那首先呢,我们来看一下事件是如何协调线程工作的,那就如果这张图所展示的有两个线程,对吧?一个是限定线程,一个是工作线程。其中,工作线程呢,
在这里插入图片描述

又称为等待线程,它会因为一个事件而睡眠,直到事件发生为止。这两个线程是如何协调工作的呢?那中间儿就要有一个公共对象在外边儿tc下,这个公共对象就是non socket server或者是physical socket server。这在我们上节课中都向你做过介绍了,对吧?

那对于工作线程来说,它要等待事件就是等待。公共对象中的某个事件,那当等待这个事件的时候呢?整个线程就处于睡眠状态。也就不工作了。而对于信令线程或者说发送事件的线程来说呢,

它会主动发送一个事件给公共对象,那当公共对象收到这个事件之后呢,就会将睡眠的线程。唤醒这样呢,这个睡眠的线程就可以继续工作了,这是事件协调线程工作的一个基本的原理OK?

那下面呢,我们再来看看web rtc下是如何这个控制事件的发生的,那对于web rtc来说,它有两个。事件的发生源那第一个呢是信令线程对吧?那信令线程可以通过主动触发事件。来调用公共对象,从而呢,唤醒等待线程,
在这里插入图片描述

这是第一个触发源,那第二个触发源呢,一般看不到。它是由系统层触发的,也就是通过socket事件来触发公共对象,从而将等待线程唤起。实际上呢,这块知识点在我们前面的课程中呢,也大概向你做了一点介绍。那这张图呢,可以使你更加清楚的了解这两个事件源好,那了解了上面这些知识之后呢,下面我们就来看一下,对于等待线程,它的处理逻辑是怎样的?
在这里插入图片描述

实际这张PPT呢,我们在之前也向你做过介绍,那对于等待线程来说,它处理逻辑非常简单,就是通过一个死循环。不断的执行,那在这个执行过程中呢,主要做两件事儿,第一件事儿呢是通过get从队列中获取消息。如果此时队列中有消息,那它就会将这个消息交给dispatch,通过dispatch函数对这个消息进行处理。那如果队列中没有消息,在get函数内部会进行等待,也就是说指当前线程处于睡眠状态,

等待时间的触发。这个逻辑呢,非常的清晰,那接下来呢,我们来看一下get函数中做了什么事,
在这里插入图片描述

那对于get函数来说呢,它有两层循环,我们来看一下。它里边逻辑是怎样的?首先我们来看看,在这个大的循环里边儿,这个小的循环,它的作用是什么?那这里呢?我们第一个看到的是获得锁,

对吧?那获得这个锁的含义是什么呢?实际这个锁就是队列锁。当两个线程对同一个队列进行操作的时候,那都需要先获得这把锁之后才能对队列进行操作。对于发送消息的线程来说,它首先要获得这把锁,之后呢,才能向队列中插入消息。而对于获取数据的线程来说呢,它也要先获得这把锁之后呢,才能从堆列中取出消息。当获得这把锁之后,我们来看get函数做了哪些事啊?它首先判断这个消息队列是否为空。

那如果为空,它直接就退出这个while循环了,对吧?那退出这个循环之后,它做哪件事呢?就是调socket server的weight函数。那在weight函数中呢,就会调用事件等待API,等待事件的触发。那如果队列不为空,它就会从队列中取出这个消息,并且呢,将消息弹出队列,并从这个函数返回。那由于p message是输出参数,

所以通过它的输出参数呢?那外层就可以拿到这个消息进行进一步的处理了,也就是交由dispatch。进行消息的处理,那所以这个逻辑啊,还是非常简单的。也就是说,在大的循环里头,包括了两块儿,一块儿呢,是对队列的操作,那当队列为空的时候呢,它就进入睡眠状态。等待信号的触发,那如果有信号过来之后。

它就会继续执行,对吧?那对于wait来说,它可以设置成永久等待,也可以设置成短时等待。如果是短时等待,当超时之后。它又通过这个外部循环进入了睡眠状态,这就是外层循环,它的作用,那内层循环呢?适用于处理消息,外层循环呢?适用于处理当wait超时之后继续等待。OK,

在这里插入图片描述

那这是get函数,那这里呢?我们还要关注一下wait函数,看看wait函数里是怎么实现的?对于位的函数来说呢,不同的socket server,它的时间是不一样的,那有non socket server和physical socket server,那这里呢,我以physical socket server为例。来看一下位的函数的实现,我们只要了解了physical socket server的实现,就可以知道non socket server它是怎么做的了。好,对于physical socket server的weight函数来说呢,

它又一层循环,对吧?在这个循环里头。有一个for循环,这个for循环呢?是用于我们将socket与事件进行绑定的,也就是调用的wsa even的select这个API。对吧,这个API呢,我们在前面已经向你做过详细介绍了,那这个API不清楚的同学可以再翻一下,上面我们讲解的内容。当所有的socket都与事件绑定之后。它会调用wsa wait for multiple events,这个API那这个API实际就是对事件进行检查。

如果事件来了,它就继续执行下面的操作,如果没有事件,它就会让这个线程呢,直接在这里。进行睡眠对吧?直到事件发生为止。那我们来看一下这个函数,它几个参数,实际这几个参数呢,我们前面也做过介绍,那第一个参数呢,就是我们这个事件数组中。一共有多少个事件对吧?第二个呢?

是事件的数组,第三个是是否所有的事件都触发才唤醒这个线程?那FALSE呢,就是只要有一个时间触发了。它就唤醒了,对吧?好,再下一个参数负一就是永远等待,直到有事件发生,这个参数呢?就是time out最后一个参数呢?我们设成了。好,那再接下来啊,如果有时间触发了对于physical socket server的weight函数来说。

它要判断是哪个socket触发的事件,这个时候呢,在这个for循环中就会调用ws a。enumerate network event这个API那在这个API中呢?它会对这个事件中的所有socket进行遍历。如果他发现输出参数evs的network events,某个事件被置位了,那他就进行相应的逻辑处理。那否则呢,如果没有任何事件,它在循环遍历下一个socket,那这就是physical socket server。它的一个主要逻辑。当对于web rtc的weight实现来说呢,它里边包含了很多代码,(这就是一个很正常的select的处理流程)

这里呢,是我将一些不重要的代码简化之后,剩下的主干代码。那通过这个主干代码,我们就可以知道它真正做了什么事了,对吧?好,那现在呢?我们就将等待线程的整个逻辑向你做了介绍,首先通过get获取消息。对吧,在get内部呢,它会进行判断是否队列为空,如果队列为空或者是没有触发socket事件。那它就会调用wait函数,

最终调用wait for multiple events,这个API使线程处于睡眠状态。那当有事件来了,或者是队列不为空了,或者是发生骚位的事件了,那这个时候呢,他会从睡眠状态唤起。那唤起之后呢,就做后边的这段逻辑对吧?对这个三维的事件进行处理,或者是从队列中取出消息。一个是s时间,延安在这整个过程,我们了解之后呢,下面我们就来看一下外边tc源码,

咱们过一下这个逻辑。好,我们切换到Windows系统下,那在这里呢?首先我们要打一些断点,在哪里打呢?实际主要就是在three的点CC这个文件中,那这个文件是在哪个目录下呢?是在rtc base下边儿的rtc base,这个工程在这个工程中呢,就包含了three的点儿CC文件。好在这个文件中呢,首先我们可以搜一下。process.那实际上这个函数我们在前面的课程中也向你做过介绍,
在这里插入图片描述

对吧?当我们找到这个process之后呢,我们看一下它的实现。这就是这里。在984行。这样呢,我们就在process message这个函数中呢,设一个断点在哪设呢?就是在993行。在这个while循环这儿,我们设一个断点,这样我们就可以看到等待线程,它的处理逻辑是怎样的了,对吧?当我们将这个断点设置好之后呢?
在这里插入图片描述

我们将peer connection clan端给启动起来。继续执行。连接新的服务器。那这块我们先不管,先继续执行。我们连接一个对端。那首先呢,它会创建peer connection factory对吧?这个我们在之前都讲过,那在创建peer connection factory的时候呢?会创建几个线程?一是网络线程,二是工作线程。那当线程启动起来之后呢?这些线程呢?

就开始工作了,对于等待线程来说,那它就会跳到while循环上去。处理消息,我们继续执行好,这是它内部去创建physical socket server,对吧?在创建。physical socket server的时候呢?在它里边,会创建一个事件hev。这个事件是用于处理消息队列的。
在这里插入图片描述

那还会创建另外一个事件是socket ev这个事件呢,是用于处理socket消息的。
在这里插入图片描述

所以它一共有两个事件源,这我们都看到了,对吧?分别是。消息队列。还有socket好,我们继续执行。
在这里插入图片描述

那通过上面这段代码呢,我们就将网络线程创建好了,接下来呢,它创建工作线程对于工作线程来说呢,它使用的是n。设位的设备。好,我们进入到这个函数中。那在这个函数中呢?
在这里插入图片描述

684行,我们可以看到。对于这个线程,它使用的是non socket server,对吧?我们继续往下走。好,这时候呢,我们就将工作线程也启动起来了,那当工作线程启动的时候呢,我们可以看到之前创建的网络线程已经处于。等待状态了,我们来看一下它的调用站。那从这个调用站中呢,我们就可以知道是网络编程处于了等待状态,
在这里插入图片描述

那首先呢,我们来看一下process message(等待线程或者说是网络线程)。那在这个函数中呢?在998行,它调用了get函数对吧?那在get函数中,首先有一个well循环。也就是442行在这个while循环的下边,又有一个while循环446行在446行这个while循环里边。它首先获得队列锁对吧?451行那拿到这个锁之后呢?它会做一堆逻辑,那这一块逻辑呢?我们暂时先不管,因为它不是核心逻辑。
在这里插入图片描述

那核心逻辑是哪块呢?是467行到472行。也就是首先判断队列是否为空,如果为空就直接退出了,退出之后它就进入睡眠状态。否则的话呢,它就从队列中取出一个消息,取出这个消息,它干什么呢?取出这个消息之后,它就直接返回了,对吧?那回到上一层,就会对获取到消息进行处理。那如果没有消息,
在这里插入图片描述

它会怎么办呢?它就会调用位的函数进行等待,对吧?好,那下面呢?我们再来看看wait函数做了哪些事情?那wait函数呢?准备执行wait for multiple events这个API了。那对于这个API来说呢,它的输入参数与我们在PPT中写的是不一样的,但是它的含义是类似的。也是事件的个数,事件数组这个为就是当有事件来了之后就立马触发。不需要等待所有的事件都来。等待超时时间最后一是那也是类似的,
在这里插入图片描述

那我们来看看位的函数主要都做了哪些事儿?那在weight函数的一开始呢,在这个循环中,首先它要构造一些事件,对吧?都有哪些事件进行侦听?那么,需要把要侦听的这些事件呢?塞到这个事件数组中。
在这里插入图片描述

之后呢,它会处理所有的socket。从每一个dispatcher中拿到它的socket的描述符。那之后呢,通过event select将这个socket与事件进行一个绑定,对吧?
在这里插入图片描述

之后呢?当有事件发生的时候,我们就可以知道是哪个socket触发的事件。好,如果我们拿到的这个socket,它不是一个真正的socket。那有可能是一个普通事件,对吧?那我们就把它当做一个普通事件,塞到事件处理函数中之后呢?就是调用wait for multiple event这个API。进行事件等待。当有线程触发了事件之后呢,它就会对返回值做一些判断,如果失败了怎么样?
在这里插入图片描述

否则成功了,它会根据返回值计算出发生事件的索引,最终呢,从事件。owner数组中取出对应的dispatcher。那么,拿到第四拍摄之后,进行相应的处理。另外呢,返回的index也是有两层含义。那一种呢,是普通的事件的index,另外一种呢,是socket index,那对于socket来说。
在这里插入图片描述

它会进入到socket处理逻辑中,就会遍历所有的dispatcher,那看看是不是对应的socket触发了事件。

如果是的话,就会进行socket枚举,最终呢,找到是谁触发的事件,从而处理相应的socket,对吧?这就是。这段逻辑,它的一个主要工作。OK,那下面呢?我们就来看一下是谁触发的事件呢?
在这里插入图片描述

你继续执行。在397行的wake up socket server就是触发事件的API。那在它内部呢,会调用socket server的wake up函数,从而呢,将等待线程换解,那下面呢,我们就通过这个调用站来看一下到底是谁?触发的这个事件。这个调用站啊,是从上到下看,也就是说最顶上的是我们最近调用的函数,最底下的呢是它的源就是谁调用的?那首先我们将调用站往下拉动,我们可以看到一个非常熟悉的身影,
在这里插入图片描述

就是create modular peer connection factory这个API。也就显然,这个事件呢,是我们在调用peer connection对象的时候触发的,对吧?在它内部呢,是做了多层的调用,那这些调用呢,我会在后边向你做介绍,那么我们再往上找找。找谁呢?找我们比较熟悉的API在这一块儿,我们会看到。当peer connection factory创建成功之后呢,它会调用initialize来对这个对象进行初始化。

初始化的时候又会创建China manager,那manager创建好之后呢,又会调用它的nit。那我们看到这个标记之后呢?往上找。你就会发现在113行有一个invoke函数。
在这里插入图片描述

那113行的含义就是向网络线程发送一个消息,那这个消息呢?就是由我们括号中的这段代码来组成的。对,也就是说,让网络线程来执行这段代码,因为是在创建peer connection factory对象,所以它一定是在信令线程。所以是信令线程调用了invoke向网络线程设置的一个任务。
在这里插入图片描述

那这个任务是什么呢?就是这个匿名函数。那这个任务就会被插入到网络线程的队列中,那我们继续执行啊。那任务插入成功之后呢,就会触发一个事件,那这个事件呢,就是由wake up socket server来触发的,那在这个函数中呢,又会调用。socket server的wake up函数。在wake up函数中,会调用signal wake up的signal方法。好在,signal方法中呢?
在这里插入图片描述

会调用。wsa set event,那像physical socket server触发一个普通事件这样呢,它又开始执行1857行以后的代码了。
在这里插入图片描述

那以上呢,就是web rtc线程事件的处理逻辑OK,那通过上面的讲解呢,你应该对。y8 rtc的事件处理逻辑非常清楚了,对吧?知道了,等待线程它都做了哪些事情?发送线程又做了哪些事情?那关于我们在代码调试过程中出现的invoke sent post等这一类函数呢?我们在后边的课程中再向你做详细介绍。

那这些呢,涉及到线程的切换,以及像其他线程队列中插入消息等,这一系列操作,那这一些呢,我们都会向你做详细介绍。那我们今天的课呢,就到这里有任何的问题呢,您可以到讨论区或者是群里去给我留言,我在那里呢,给你做详细解答好,谢谢。

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

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

相关文章

简单5步骤搞定windows server2019 配置IIS支持PHP

测试成功,记录一笔,感谢网上各位大佬的技术支持。 一、安装vcredist_x64.exe 否则可能会出现 FastCGI进程意外退出 二、IIS开启CGI(可能需要重启) 控制面板,启用或关闭windows程序,IIS--应用程序开发--CGI…

java封装国密SM4为 jar包,PHP调用

java封装国密SM4为 jar包,PHP调用 创建java工程引入SM4 jar包封装CMD可调用jar包PHP 传参调用刚用java弄了个class给php调用,本以为项目上用到java封装功能的事情就结束了,没想到又来了java的加密需求,这玩意上头,毕竟不是强项,没办法,只好再次封装。 但是这次的有点不…

CSS笔记(黑马程序员pink老师前端)盒子阴影,文字阴影

盒子阴影 属性值为box-shadow,盒子阴影不占空间,不影响盒子之间的距离. 值说明h-shadow必需,水平阴影位置,允许为负值v-shadow必需,水平阴影位置,允许为负值blur可选,模糊距离,数值越大影子越模糊spread可选,影子的尺寸color可选,影子的颜色inset可选, 将外阴影改为内阴影(省…

GO语言网络编程(并发编程)Goroutine池

GO语言网络编程(并发编程)Goroutine池 1. Goroutine池 1.1.1. worker pool(goroutine池) 本质上是生产者消费者模型可以有效控制goroutine数量,防止暴涨需求: 计算一个数字的各个位数之和,例…

router-link 和 router-view的区别

router-link 实现路由之间的跳转 router-view(路由出口组件 -> 渲染路径匹配到的视图组件) 当你访问的地址与路由path相符时,会将指定的组件替换该router-view router-link router-link 点击实现路由跳转,to属性指向目标地址&…

VM+Ubuntu+Xshell+Xftp安装教程

目录 VM17安装教程 检查网络连接 Ubuntu环境搭建 UBUNTU 系统配置 1、 SSH 服务器配置 服务端(必须) 1.安装 ssh 服务端 2.确认 sshserver 是否启动了(看见 sshd 说明已启动) 3.启动 sshserver 4.SSH 配置(如果…

【科普向】Jmeter 如何测试接口保姆式教程

现在对测试人员的要求越来越高,不仅仅要做好功能测试,对接口测试的需求也越来越多!所以也越来越多的同学问,怎样才能做好接口测试? 要真正的做好接口测试,并且弄懂如何测试接口,需要从如下几个…

【数据结构面试题】栈与队列的相互实现

目录 1.队列实现栈 1.1创建栈 1.2判断是否为空 1.3入栈 1.4出栈 1.5获取栈顶元素 1.6完整代码 2. 用栈实现队列 2.1创建队列 2.2判断是否为空 2.3入队列 2.4出队列 2.5获取队头元素 2.6完整代码 1.队列实现栈 用队列实现栈https://leetcode.cn/problems/impleme…

软件设计模式(三):责任链模式

前言 前面荔枝梳理了有关单例模式、策略模式的相关知识,这篇文章荔枝将沿用之前的写法根据示例demo来体会这种责任链设计模式,希望对有需要的小伙伴有帮助吧哈哈哈哈哈哈~~~ 文章目录 前言 责任链模式 1 简单场景 2 责任链模式理解 3 Java下servl…

【MFC】实现简单UDP通信

创建项目,初始化套接字 创建一个基于对话框的MFC项目(名称为UDP),高级功能选中Windows套接字 这个时候在CUDP类的InitInstance()方法中就会出现这样的代码用来初始化套接字 if (!AfxSocketInit()) {AfxMessageBox(IDP_SOCKETS_…

嵌入式基础知识-信息安全与加密

本篇来介绍计算机领域的信息安全以及加密相关基础知识,这些在嵌入式软件开发中也同样会用到。 1 信息安全 1.1 信息安全的基本要素 保密性:确保信息不被泄露给未授权的实体。包括最小授权原则、防暴露、信息加密、物理加密。完整性:保证数…

让GPT成为您的科研加速器丨GPT引领前沿与应用突破之GPT4科研实践技术与AI绘图

GPT对于每个科研人员已经成为不可或缺的辅助工具,不同的研究领域和项目具有不同的需求。如在科研编程、绘图领域:1、编程建议和示例代码:无论你使用的编程语言是Python、R、MATLAB还是其他语言,都可以为你提供相关的代码示例。​2、数据可视化…

LeetCode 34. 在排序数组中查找元素的第一个和最后一个位置

题目链接 力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台 题目解析 使用二分查找的方式,分左右端进行查找。首先使用二分找到左端的端点下标,然后在使用二分找到右端的端点下标。 注意事项 求mid注意事项 在使用二分找左端…

jvm 程序计算器 程序计数器是否溢出 程序计数器是做什么的 java程序计数器会内存溢出吗 程序计数器作用与用处 jvm内存模型 jvm合集(一)

1. jvm内存模型: 内存模型: 程序计数器 堆 栈 本地方法栈 方法区 2. java代码编译为class文件,由类加载器加载到jvm,然后由解释器,jit即时编译到机器码,机器码再到cpu执行 3. 程序计数器: 是一块较小的内存…

记录一次IDEA非法字符‘\ufeff‘报错

✅作者简介:大家好,我是Leo,热爱Java后端开发者,一个想要与大家共同进步的男人😉😉 🍎个人主页:Leo的博客 💞当前专栏: 报错以及Bug ✨特色专栏: …

Hadoop生态之hive

一 概述与特点 之所以把Hive放在Hadoop生态里面去写,是因为它本身依赖Hadoop。Hive是基于Hadoop的一个数据仓库工具,可以将结构化的数据文件映射为一张数据库表,并提供类 SQL 查询功能。 其本质是将 SQL 转换为 MapReduce/Spark 的任务进行运算,底层由 HDFS 来提供…

[uniapp]踩坑日记 unexpected character > 1或‘=’>1 报错

在红色报错文档里下滑&#xff0c;找到Show more 根据提示看是缺少标签&#xff0c;如果不是缺少标签&#xff0c;看看view标签内容是否含有<、>、>、<号,把以上符合都进行以<号为例做{{“<”}}处理

动态表单设计

动态表单设计 背景方案讨论基于上面分析&#xff0c;对比调研&#xff0c;自定义动态表单数据模型表单详解&#xff08;一&#xff09; 表单模板&#xff1a;jim_dynamic_form&#xff08;二&#xff09;表单数据类型&#xff1a;jim_form_data_type&#xff08;三&#xff09;…

基于SSM的学生公寓管理中心系统设计与实现

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;采用JSP技术开发 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#x…

Android笔记(二十九):利用python自动生成多语言

背景 项目需要支持十几种多语言&#xff0c;而且每个版本的新功能ui都有很多地方需要多语言&#xff0c;如果手动添加非常耗时&#xff0c;于是设计了一个python脚本&#xff0c;通过excel表格转化多语言到项目values/strings文件内 步骤 android工程项目结构 脚本位于langu…