丹灶网站建设seo搜狗

web/2025/9/29 9:26:35/文章来源:
丹灶网站建设,seo搜狗,淘宝网站建设策划书,学校做网站需要什么目录 线程的声明 线程创建过程 向线程中投递消息 从消息队列中取消息的具体实现 处理线程消息 webrtc线程模块的实现逻辑在 rtc_base\thread.h 文件中 比如想创建一个线程#xff1a; //声明要创建的线程指针#xff0c;通过智能指针管理 std::unique_ptrrtc::Thr…目录 线程的声明 线程创建过程 向线程中投递消息 从消息队列中取消息的具体实现 处理线程消息 webrtc线程模块的实现逻辑在 rtc_base\thread.h 文件中 比如想创建一个线程 //声明要创建的线程指针通过智能指针管理 std::unique_ptrrtc::Thread video_thread_; // 创建线程 video_thread_ rtc::Thread::Create(); //设置新创建的线程名 video_thread_-SetName(video_thread_, video_thread_.get()); //开启线程 video_thread_-Start(); //向线程投递要处理的消息video_thread_-Post(RTC_FROM_HERE, this, MESSAGE_ID);// MESSAGE_ID 自定义的消息id//向线程投入带有消息体的消息video_thread_-Post(RTC_FROM_HERE, this, VIDEO_INFO,new rtc::TypedMessageDataVIDEO_INFO_MEESAGE(r));//其中RTC_FROM_HERE 是个宏定义标记线程调用的原位置 // Define a macro to record the current source location. #define RTC_FROM_HERE RTC_FROM_HERE_WITH_FUNCTION(__FUNCTION__) 下面看下线程的具体实现 线程的声明 //线程继承自一个任务队列并且有两个存储消息的消息队列 //普通消息 messages_延时消息 delayed_messages_ class RTC_LOCKABLE RTC_EXPORT Thread : public webrtc::TaskQueueBase {explicit Thread(SocketServer* ss);explicit Thread(std::unique_ptrSocketServer ss);privateMessage msgPeek_;//声明对应的消息//MessageList 具体的定义//typedef std::listMessage MessageList;MessageList messages_ RTC_GUARDED_BY(crit_); //延时队列继承自 std::priority_queueDelayedMessage PriorityQueue delayed_messages_ RTC_GUARDED_BY(crit_); uint32_t delayed_next_num_ RTC_GUARDED_BY(crit_); } 创建线程的实现 //具体的创建函数 //构造中传入一个 NullSocketServer() 作为参数 std::unique_ptrThread Thread::Create() {return std::unique_ptrThread(new Thread(std::unique_ptrSocketServer(new NullSocketServer()))); }//最终调用到这里线程构造函数 Thread::Thread(SocketServer* ss, bool do_init): fPeekKeep_(false),delayed_next_num_(0),fInitialized_(false),fDestroyed_(false),stop_(0),ss_(ss) {RTC_DCHECK(ss);//把当前线程的this指针传给 NullSocketServerss_-SetMessageQueue(this); //设置线程的初始名字SetName(Thread, this); // default nameif (do_init) {DoInit();} }void Thread::DoInit() {if (fInitialized_) {return;}fInitialized_ true;//把当前线程的this指针对象传给ThreadManagerThreadManager::Add(this); } //ThreadManager会把当前线程放到一个 message_queues_ 中统一管理 void ThreadManager::AddInternal(Thread* message_queue) {CritScope cs(crit_);// Prevent changes while the list of message queues is processed.RTC_DCHECK_EQ(processing_, 0);message_queues_.push_back(message_queue); } 引入了一个新的对象 ThreadManager //ThreadManager是线程管理类是一个单例 //保存创建的所有线程对象 class RTC_EXPORT ThreadManager {// Singleton, constructor and destructor are private.static ThreadManager* Instance();//保存线程的消息队列其实是个vector不是queue。//很多服务都喜欢用vector代替queuesrs也是把vector当queue用// This list contains all live Threads.std::vectorThread* message_queues_ RTC_GUARDED_BY(crit_);} //创建单例 ThreadManager饿汉模式 ThreadManager* ThreadManager::Instance() {static ThreadManager* const thread_manager new ThreadManager();return thread_manager; } //把线程指针加入到消息队列中 void ThreadManager::Add(Thread* message_queue) {return Instance()-AddInternal(message_queue); } void ThreadManager::AddInternal(Thread* message_queue) {CritScope cs(crit_);// Prevent changes while the list of message queues is processed.RTC_DCHECK_EQ(processing_, 0);message_queues_.push_back(message_queue); } 线程创建过程 线程的Start()函数才是真正创建线程的地方只看android即linux端。 具体的实现是用的pthread而没有用标准的std::thread bool Thread::Start() {pthread_attr_t attr;pthread_attr_init(attr);//创建线程调用的是pthread_create//并传入线程函数 PreRunint error_code pthread_create(thread_, attr, PreRun, this);if (0 ! error_code) {RTC_LOG(LS_ERROR) Unable to create pthread, error error_code;thread_ 0;return false;} }void* Thread::PreRun(void* pv) {Thread* thread static_castThread*(pv);ThreadManager::Instance()-SetCurrentThread(thread);rtc::SetCurrentThreadName(thread-name_.c_str());//调用一个Run()函数thread-Run();}void Thread::Run() { // Forever 模式一直轮训处理ProcessMessages(kForever); } //真正处理消息的函数下文会详细介绍 bool Thread::ProcessMessages(int cmsLoop) {while (true) {Message msg;// Get()函数从消息队列中取消息 if (!Get(msg, cmsNext))return !IsQuitting();//取出消息后调用Dispatch()进行处理Dispatch(msg);if (cmsLoop ! kForever){cmsNext static_castint(TimeUntil(msEnd));if (cmsNext 0)return true;}} }向线程中投递消息 // |time_sensitive| is deprecated and should always be false.virtual void Post(const Location posted_from,//是从哪个函数向线程中投递消息MessageHandler* phandler,//消息处理的类一般是向线程抛消息的类的this指针当线程轮训到该消息时通过该this指针再回调对应的处理函数uint32_t id 0,//消息idMessageData* pdata nullptr, //消息体bool time_sensitive false);//废弃的参数virtual void PostDelayed(const Location posted_from, //支持向线程抛入延迟消息int delay_ms,MessageHandler* phandler,uint32_t id 0,MessageData* pdata nullptr);virtual void PostAt(const Location posted_from, int64_t run_at_ms,MessageHandler* phandler,uint32_t id 0,MessageData* pdata nullptr);// 看下Post的具体实现void Thread::Post(const Location posted_from,MessageHandler* phandler,uint32_t id,MessageData* pdata,bool time_sensitive) {RTC_DCHECK(!time_sensitive);if (IsQuitting()) {delete pdata;return;}// Keep thread safe// Add the message to the end of the queue// Signal for the multiplexer to return{//注意这个大括号哈//数据进队列加锁内部用的 pthread_mutex_lock(mutex_)//CritScope对 mutex_进行了封装构造函数加锁、析构函数解锁CritScope cs(crit_);Message msg;//构造消息体msg.posted_from posted_from;msg.phandler phandler;msg.message_id id;msg.pdata pdata;messages_.push_back(msg);}//CritScope退出作用区域后调用对应的析构函数解锁//即pthread_mutex_unlock(mutex_);函数//这种实现方式一方面缩小了锁的范围锁的范围仅仅局限于大括号内部而不是整个Post()函数//同时退出临界区后自动调用析构函数释放锁也避免了死锁的可能性//这个WakeUp* 函数是重点它会唤醒当前等待的线程WakeUpSocketServer(); } //看一下 WakeUpSocketServer()的实现 //最终是通过 pthread_cond_broadcast() //唤醒当前所有处于pthread_cond_wait()的线程void Thread::WakeUpSocketServer() {ss_-WakeUp(); } void NullSocketServer::WakeUp() {event_.Set(); } void Event::Set() {pthread_mutex_lock(event_mutex_);event_status_ true;//广播唤醒所有处于 pthread_cond_wait()的线程pthread_cond_broadcast(event_cond_);pthread_mutex_unlock(event_mutex_); } 从消息队列中取消息的具体实现 //消息处理是从 Thread 的Run()函数开始 void Thread::Run() {// KForever字段一直轮训取数据//没有数据时会 wait() 阻塞等待ProcessMessages(kForever); } bool Thread::ProcessMessages(int cmsLoop) {int cmsNext cmsLoop;while (true) {Message msg;//从消息队列中取消//取出来后交给 Dispatch()进行处理if (!Get(msg, cmsNext))return !IsQuitting();Dispatch(msg);if (cmsLoop ! kForever) {cmsNext static_castint(TimeUntil(msEnd));if (cmsNext 0)return true;}} } //取消息的过程 bool Thread::Get(Message* pmsg, int cmsWait, bool process_io) {// Return and clear peek if present// Always return the peek if it exists so there is Peek/Get symmetryif (fPeekKeep_) {*pmsg msgPeek_;fPeekKeep_ false;return true;}// Get w/wait timer scan / dispatch socket / event multiplexer dispatchint64_t cmsTotal cmsWait;int64_t cmsElapsed 0;int64_t msStart TimeMillis();int64_t msCurrent msStart;while (true) {// Check for posted eventsint64_t cmsDelayNext kForever; //一直训练bool first_pass true;//具体实现是两层while(true)。内部的while负责取消息//取不到时外部while负责wait()阻塞等待while (true) {// All queue operations need to be locked, but nothing else in this loop// (specifically handling disposed message) can happen inside the crit.// Otherwise, disposed MessageHandlers will cause deadlocks.{//和像线程中投递消息类似取消息时也先加锁CritScope cs(crit_);// On the first pass, check for delayed messages that have been// triggered and calculate the next trigger time.if (first_pass) {//线程被唤醒后只从延时队列中取一次//并且这一次会把所有到时需要处理的延时消息取完//取出的延时消息放到messages_队列和普通消息一样进行处理first_pass false;while (!delayed_messages_.empty()) {//当前时间小于延时队列中第一条消息时间//说明还没有到需要处理延时消息的时间,if (msCurrent delayed_messages_.top().run_time_ms_) {//cmsDelayNext计算出需要等待的时间,//也是后面线程wait()时需要等待的最大时间//因为到了这个时间即便没有普通消息到来//延时队列中的消息也到时间需要处理了cmsDelayNext TimeDiff(delayed_messages_.top().run_time_ms_, msCurrent);break;}//把到时需要处理的延时消息放到普通队列中一起处理messages_.push_back(delayed_messages_.top().msg_);//延时消息出队列delayed_messages_.pop();}}// Pull a message off the message queue, if available.if (messages_.empty()) {break;} else {//真正获得需要处理消息的地方*pmsg messages_.front();messages_.pop_front();}} // crit_ is released here.// If this was a dispose message, delete it and skip it.//如果是dispose废除的消息就会删除//然后 continue()继续去取if (MQID_DISPOSE pmsg-message_id) {RTC_DCHECK(nullptr pmsg-phandler);delete pmsg-pdata;*pmsg Message();continue;}//如果是需要处理的消息就return退出当前 Get()函数//进行后面的Disptch()处理return true;}if (IsQuitting())break;// Which is shorter, the delay wait or the asked wait?int64_t cmsNext;if (cmsWait kForever) {cmsNext cmsDelayNext;} else {cmsNext std::maxint64_t(0, cmsTotal - cmsElapsed);if ((cmsDelayNext ! kForever) (cmsDelayNext cmsNext))cmsNext cmsDelayNext;}// 如果延时消息队列和普通的消息队列中都没有消息//内部while(true)会调用 break退出//然后就调用到这里,因为我们是 KForever一直轮训模式//所以当队列中没有消息时防止一直遍历查询,//会通过wait()挂起当前线程让出时间片{// Wait and multiplex in the meantime//内部调用的是 pthread_cond_wait//并且在wait()时也加了锁if (!ss_-Wait(static_castint(cmsNext), process_io))return false;}// If the specified timeout expired, returnmsCurrent TimeMillis();cmsElapsed TimeDiff(msCurrent, msStart);if (cmsWait ! kForever) {if (cmsElapsed cmsWait)return false;}}return false; } 处理线程消息 从消息队列中Get(获取消息后会调用 Dispatch()处理消息。具体实现就是回调向线程中抛消息的类的OnMessage(pmg)函数然后进行具体消息的处理 void Thread::Dispatch(Message* pmsg) {TRACE_EVENT2(webrtc, Thread::Dispatch, src_file,pmsg-posted_from.file_name(), src_func,pmsg-posted_from.function_name());int64_t start_time TimeMillis();//回调对应OnMessage(pmsg)函数进行消息处理pmsg-phandler-OnMessage(pmsg);int64_t end_time TimeMillis();int64_t diff TimeDiff(end_time, start_time);if (diff kSlowDispatchLoggingThreshold) {RTC_LOG(LS_INFO) Message took diff ms to dispatch. Posted from: pmsg-posted_from.ToString();} } 而我们的处理类继承 rtc::MessageHandler并实现了 OnMessage()函数就可以基于对应的MessageID类型处理不同的消息了 CVideoThread::OnMessage(rtc::Message* msg) {switch case:Message_id:handlerMessage();case VIDEO_INFO: //假如向线程中传入了 MessageData//在线程回调时会把这个消息体带出来方便我们处理if(msg-pdata){rtc::TypedMessageDataVideoMessageData* data static_castrtc::TypedMessageDataVideoMessageData*(msg-pdata);string message data-data();delete data;data nullptr;}default:break; } 以上就是webrtc的线程模块了下一篇会介绍webrtc的 TaskQueue 任务队列

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

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

相关文章

合浦县城乡规划建设局网站网站怎样建设才叫人性化

前言 扁平化概念的核心意义 去除冗余、厚重和繁杂的装饰效果。而具体表现在去掉了多余的透视、纹理、渐变以及能做出3D效果的元素,这样可以让“信息”本身重新作为核心被凸显出来。同时在设计元素上,则强调了抽象、极简和符号化。 示例 视频效果&…

英语网站online店匠怎么做网页

经过实践,weblogic节点管理器的作用主要有两点: 1、可通过weblogic控制台远程控制被管server启停。 2、可以自动重启被管server的进程,并且对spring框架提供比直接启动更快的重启速度。 配置步骤: 在管理电脑上: …

导购网站怎么做有特色北京海淀房管局网站

gizp压缩是一种http请求优化方式,通过减少文件体积来提高加载速度。html、js、css文件甚至json数据都可以用它压缩,可以减小60%以上的体积。 webpack在打包时可以借助 compression webpack plugin 实现gzip压缩,首先需要安装该插件&#xff…

勒流网站制作端午节网站建设目的

l 在iOS中想实现一些简单的动画效果(平移、缩放、旋转),特别简单 l 你只需要告诉iOS系统:哪些代码造成的改变需要使用动画效果就可以了 [UIView beginAnimations:nil context:nil]; ……需要执行动画效果的代码…… [UIView c…

游戏ui设计网站鞍山网站

Given a string and we have to split into array of characters in Python. 给定一个字符串,我们必须在Python中拆分为字符数组。 将字符串拆分为字符 (Splitting string to characters) 1) Split string using for loop 1)使用for循环分割字符串 Use for loop t…

html5导航网站源码wordpress发表的文章点不开

在主成分分析(PCA)原理总结中,我们对主成分分析(以下简称PCA)的原理做了总结,下面我们就总结下如何使用scikit-learn工具来进行PCA降维。 一、scikit-learn PCA类介绍 在scikit-learn中,与PCA相关的类都在sklearn.deco…

软件开发顺序wordpress媒体优化

在工作中遇到对接java接口,涉及到java加密或签名问题,.net无法实。就将java代码编辑为dll给.net调用 注:这里只做简单java代码处理,不涉及到复杂的java包 java文件处理: 第一步:简单java代码 package com.zht;//c#命名…

php 怎么做视频网站wordpress 付费注册

转载于:https://www.cnblogs.com/cmyg/p/7206474.html

网站建设:什么是网站开发与建设

1.题目 如果在将所有大写字符转换为小写字符、并移除所有非字母数字字符之后,短语正着读和反着读都一样。则可以认为该短语是一个 回文串 。 字母和数字都属于字母数字字符。 给你一个字符串 s,如果它是 回文串 ,返回 true ;否…

优化网站用什么软件好做外贸没有企业网站

DFS 蓝桥杯中的DFS主要有针对分配过程的DFS和图/树的DFS两种类型,基本是模板题,难度中等 类型一:针对分配过程的DFS 例题 1:飞机降落 题目描述: N 架飞机准备降落到某个只有一条跑道的机场。其中第 i 架飞机在 T …

西安网站seo外包seo入门讲解

使用docker-compose优雅部署RocketMQ 随着市场的发展,越来越多的复杂场景出现在我们日常的开发工作中。随之也越来越多的好的工具,也同步出现在程序员的学习范围清单内。好的工具提高产品性能的同时,也带来了很多安装上的问题,do…

什么网站百度容易收录线上直播营销策划方案

随着区块链技术的迅速发展和数字资产市场的蓬勃发展,区块链交易所成为了数字资产交易的核心场所之一。在这个快速发展的领域中,区块链交易所App系统的开发和撮合交易系统的建设至关重要。本文将探讨区块链交易所App系统开发及撮合交易系统的重要性&#…

合肥有什么好的网站建设公司win7优化配置的方法

给定一个整数数组 nums ,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。 思路:每个循环中,sum表示以nums[i]结尾的最大子序和,res表示目前得到的最大子序和。当循环结…

推广链接网站小程序开发定制公司北京

1. 数据库基础 1.1 什么是数据库 存储数据用文件就可以了,为什么还要弄个数据库? 文件保存数据有以下几个缺点: 文件的安全性问题文件不利于数据查询和管理文件不利于存储海量数据文件在程序中控制不方便 数据库存储介质: 磁盘内存 为…

广州网站建设开发公司建设银行深圳天健世纪支行网站

BeetleX针对redis访问封了全async/await操作模式,通过它可以更高效地访问redis服务。BeetleX.Redis提供读写分离和多机故意写入处理,同时安全的TLS访问机制,在使用功能上组件支持绝大部分基础指令,并提供json,protobuf…

手机端网站源码抖音带运营的执行老大

在当今信息化快速发展的时代,手机已经成为我们生活中不可或缺的一部分。随着资料的积累,备份手机数据成了一个重要的问题。本文将介绍iMazing如何备份手机资料,并为大家解答“iPhone的资料可以传到iPad里吗”这一问题。这不仅可以帮助你有效管…

怎么制作网站链接用wordpress做企业门户

网络基础(一) 文章目录 一、计算机网络背景1.1网络发展1.2认识“协议” 二、网络协议初识2.1OSI七层模型2.2OSI五层模型 三、网络传输基本流程3.1局域网通信3.2网络传输流程不跨子网的网络传输跨子网的网络传输 3.3网络中的地址管理IP地址MAC地址 一、计…

木质家居 技术支持 东莞网站建设自适应式网站模板

RpcProvider&#xff08;服务提供者&#xff09;实现思路 上一节说到&#xff0c;如何将一个本地服务发布成远程服务&#xff0c;但没有说明一个rpc框架怎么进行调用的&#xff0c;看看上节代码 #include <iostream> #include <string> #include "user.pb.h…

网站建设海报图片国外品牌vi设计

引言 数字化转型是当今商业领域中的关键议题&#xff0c;它不仅是技术的应用&#xff0c;更是一种战略性的变革&#xff0c;对企业而言具有重要意义。在这个数字化时代&#xff0c;企业需要不断适应和采纳新技术&#xff0c;以获得竞争优势并提高效率。 数字化转型旨在将传统业…

网站使用特殊字体陇西做网站的广告店

同步任务是指在多个线程之间协调执行的任务&#xff0c;其目的是确保多个任务按照一定的顺序和规则执行&#xff0c;例如使用锁来防止数据竞争。 同步任务的实现需要考虑多个线程之间的协作和同步&#xff0c;以确保数据的正确性和程序的正确执行。 由于TaskPool偏向于单个独…