「深入解析 Chromium Message Pump:消息循环的核心驱动」

MessagePump 是 Chromium 中 消息循环(Message Loop) 的核心组件之一,负责在不同平台上管理和分发消息、事件,并协调任务调度。

在浏览器这样的 GUI 应用中,事件循环(Event Loop)是非常重要的,它处理:

  • UI 事件(鼠标、键盘输入等)。

  • 定时任务setTimeoutsetInterval、Chromium 内部的 PostDelayedTask)。

  • 异步 I/O(如网络请求、文件读写等)。

  • 任务队列(如 TaskRunner 调度的任务)。

  • 平台特定的消息机制(如 Windows 的 GetMessage,Mac 的 NSRunLoop)。


1. MessagePump 的核心作用

MessagePump 作为 Chromium 消息循环的底层抽象,它的职责包括:

  • 管理消息队列,确保任务按正确的顺序执行。

  • 调度任务,处理异步任务、定时任务(如 ScheduleDelayedWork)。

  • 与操作系统的事件系统交互,如 Windows 消息循环(WM_*)、Linux 的 epoll 或 macOS 的 CFRunLoop

  • 支持 UI、I/O、计算等不同类型的任务调度,不同的 MessagePump 子类适用于不同场景。


2. 代码解析

(1)类定义

class BASE_EXPORT MessagePump {

  • BASE_EXPORT 用于控制符号导出,确保 MessagePump 可被不同模块访问。

  • MessagePump抽象基类,不同平台(Windows、Mac、Linux)会有对应的子类实现,如:

    • MessagePumpForUI(UI 线程消息循环)。

    • MessagePumpForIO(异步 I/O 处理)。

    • MessagePumpForWorkQueue(任务队列管理)。


(2)MessagePump::Delegate(消息循环的回调接口)

class BASE_EXPORT Delegate {

  • MessagePump 依赖 Delegate 处理具体的任务调度和执行逻辑。

  • Delegate 提供的方法:

    • DoWork():执行一次任务,并返回 NextWorkInfo 告诉 MessagePump 何时调用 DoWork()

    • DoIdleWork():当队列中没有任务时执行的 空闲任务

    • BeforeWait():在 MessagePump 进入等待状态前调用(例如 UI 线程等待新的事件)。

    • BeginNativeWorkBeforeDoWork():如果 MessagePump 需要处理平台特定的事件(如 Windows 消息队列),可使用此方法。

struct NextWorkInfo { TimeTicks delayed_run_time; // 下一个任务的运行时间 TimeDelta leeway; // 任务调度的灵活度 TimeTicks recent_now; // 当前时间戳 bool yield_to_native = false; // 是否优先处理系统事件 };

  • NextWorkInfo 告诉 MessagePump 下一次应该做什么

    • is_immediate():是否有任务 需要立即执行

    • delayed_run_time:如果任务有延迟执行时间,则存储该时间点。

示例

Delegate::NextWorkInfo next_work_info = delegate->DoWork(); if (next_work_info.is_immediate()) { // 立即执行下一个任务 } else { // 等待,直到下一个任务需要执行 }


(3)Run(Delegate* delegate)(核心事件循环)

virtual void Run(Delegate* delegate) = 0;

  • 这是 MessagePump 运行消息循环的 入口,所有消息处理都发生在这里。

  • 逻辑:

    1. 处理系统消息(如鼠标/键盘输入)。

    2. 执行 DoWork() 任务。

    3. 进入 空闲等待,直到有新的事件触发。

消息循环的伪代码

for (;;) { bool did_native_work = DoNativeWork(); // 处理 UI / I/O 事件 if (should_quit_) break; Delegate::NextWorkInfo next_work_info = delegate->DoWork(); // 运行任务 if (should_quit_) break; if (did_native_work || next_work_info.is_immediate()) continue; delegate->DoIdleWork(); // 执行空闲任务 if (should_quit_) break; WaitForWork(); // 进入等待(等待新任务) }

  • UI 线程可能包含 DoNativeWork(),确保 UI 事件(如鼠标、键盘)不会卡住。

  • WaitForWork() 使线程 进入等待状态,避免 CPU 空转。


(4)Quit()(退出消息循环)

virtual void Quit() = 0;

  • MessagePump 立即退出,常用于:

    • 窗口关闭时,主事件循环退出。

    • 单元测试,防止死循环。


(5)ScheduleWork()(立即调度任务)

virtual void ScheduleWork() = 0;

  • 确保 DoWork() 尽快被调用,一般用于:

    • 异步任务触发(如 PostTask() 调度)。

    • 优先级较高的任务

示例:

ScheduleWork(); // 让消息循环立即唤醒执行任务


(6)ScheduleDelayedWork()(定时任务调度)

virtual void ScheduleDelayedWork( const Delegate::NextWorkInfo& next_work_info) = 0;

  • 设定 定时任务,当 next_work_info.delayed_run_time 到达时执行任务。

  • 适用于:

    • 定时器(setTimeout, setInterval)

    • 异步任务的延迟调度

示例:

Delegate::NextWorkInfo info; info.delayed_run_time = base::TimeTicks::Now() + base::Milliseconds(500); ScheduleDelayedWork(info); // 500ms 后执行任务


3. 关键子类

MessagePump 是一个 抽象类,不同的 MessagePump 适用于不同的任务类型:

子类用途
MessagePumpForUI处理 UI 事件(Windows GetMessage,macOS NSRunLoop
MessagePumpForIO处理 I/O 事件(如 epoll, WSAAsyncSelect
MessagePumpForWorkQueue处理普通任务队列

示例:

std::unique_ptr<MessagePump> pump = MessagePump::Create(MessagePumpType::UI);


4. MessagePump 在 Chromium 浏览器中的作用

在 Chromium 浏览器中,MessagePump 主要用于:

  1. 主 UI 线程MessagePumpForUI

    • 处理 用户输入(鼠标、键盘)。

    • 处理 窗口消息WM_PAINT,窗口重绘)。

    • 触发 页面渲染任务

  2. 网络线程MessagePumpForIO

    • 监听 Socket 事件(如 HTTP 请求)。

    • 处理 异步 I/O 任务

  3. 定时任务ScheduleDelayedWork

    • 实现 JavaScript 的 setTimeout()

    • 控制 动画帧渲染(如 requestAnimationFrame)。


5. 结论

  • MessagePumpChromium 事件循环的核心组件

  • Run() 方法控制消息循环,不断执行任务、处理事件

  • ScheduleWork()ScheduleDelayedWork() 支持异步任务调度

  • Delegate::NextWorkInfo 决定何时执行下一个任务

  • 不同的子类 适用于 UI、I/O、定时任务等不同场景

如果你在 浏览器崩溃分析优化事件调度 方面做了工作,可以深入研究 MessagePump 及其子类的行为,看看是否有 任务调度异常、线程阻塞、CPU 占用高 等问题,并在你的汇报中体现对 事件驱动架构的理解

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

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

相关文章

3d pose 指标和数据集

目录 3D姿态估计、3维重建指标: 数据集 EHF数据集 SMPL-X 3D姿态估计、3维重建指标: MVE、PMVE 和 p-MPJPE 都是用于评估3D姿态估计、三维重建等任务中预测结果与真实数据之间误差的指标。 MVE (Mean Vertex Error):是指模型重建过程中每个顶点的预测位置与真实位置之间…

大智慧大数据面试题及参考答案

目录 MySQL 的事务隔离级别是什么? MySQL 的覆盖索引是怎样的? MySQL 常用的存储引擎有哪些,它们之间的区别是什么? 在 MySQL 中,如果读取很大的数据集,同时进行一边 select 一边写入操作,结果会怎样? 当 ES 出现分词错误的情况时,应该如何处理? Kafka 如何保证…

微服务的简单认识

目录 一、微服务架构简介 二、微服务架构风格和分布式系统架构的关系 三、微服务组成 一、微服务架构简介 微服务是一种构建分布式系统的架构风格,它将一个大型的应用程序拆分成多个小型的、独立部署的服务单元,每个服务单元都专注于特定的业务功能,并通过轻量级的通信机…

Spring的 @Conditional @ConditionalOnProperty 注解 笔记250330

Spring的 Conditional ConditionalOnProperty 注解 Spring 的 Conditional 与 ConditionalOnProperty 注解详解 在 Spring 框架中&#xff0c;Conditional 和 ConditionalOnProperty 是用于动态控制 Bean 注册的重要注解。虽然它们都服务于条件化配置&#xff0c;但定位和使用…

电路学习——MOS栅极驱动电阻取值(2025.03.30)

参考链接1: 驱动芯片的驱动电流的选型和计算 参考链接2: NMOS栅极驱动电阻Rg阻值和功率的计算&#xff0c;NMOS栅极驱动电阻Rg的作用&#xff0c;如何防止NMOS误开通 单片机直接驱动NMOS的方法 RLC谐振电路 智能车BLDC 在此感谢各位前辈大佬的总结&#xff0c;写这个只是为了记…

mysql JSON_ARRAYAGG联合JSON_OBJECT使用查询整合(数组对象)字段

父表数据&#xff08;表名&#xff1a;class&#xff09; idname1一年级2二年级3三年级 子表数据&#xff08;表名&#xff1a;students&#xff09; idnameclassId11张三112李四113小明3 关联子表sql查询&#xff08;推荐使用方法一&#xff09; 方法一 (使用IFNull判断子…

张量-pytroch基础(2)

张量-pytroch网站-笔记 张量是一种特殊的数据结构&#xff0c;跟数组&#xff08;array&#xff09;和矩阵&#xff08;matrix&#xff09;非常相似。 张量和 NumPy 中的 ndarray 很像&#xff0c;不过张量可以在 GPU 或其他硬件加速器上运行。 事实上&#xff0c;张量和 Nu…

marked库(高效将 Markdown 转换为 HTML 的利器)

文章目录 前言使用基本使用自定义渲染器例子 代码高亮 前言 最近尝试了一下通过星火大模型将ai引入到项目上&#xff0c;但是ai返回的数据可以显而易见的发现是markedown语法的&#xff0c;那么就需要一个工具&#xff0c;将类似这种的格式转换为markdown格式 Marked 是一个用…

调用deepseek大模型时智能嵌入函数

DeepSeek-R1 当前炙手可热,以其强大的自然语言处理和推理能力而广受赞誉。饶是如此,却并不原生支持函数调用(function_call),这是开发过程中不可或缺的一部分。虽有第三方调校的模型支持,然终非官方自带,还需假以时日。本文虽然简短,应该是全网写得最通透的了吧。 …

SQLMesh系列教程:基于指标构建一致的分析语义层应用实践

本文深入探讨SQLMesh指标框架的核心概念、定义方法及应用场景。通过统一的语义层管理&#xff0c;SQLMesh解决了数据分析中指标定义不一致的痛点&#xff0c;实现了跨团队协作的数据一致性。文章包含指标定义语法详解、自动表连接机制解析、派生指标构建方法&#xff0c;并通过…

基于OpenCV+MediaPipe手部追踪

一、技术栈 1. OpenCV&#xff08;Open Source Computer Vision Library&#xff09; 性质&#xff1a;开源计算机视觉库&#xff08;Library&#xff09; 主要功能&#xff1a; 图像/视频的基础处理&#xff08;读取、裁剪、滤波、色彩转换等&#xff09; 特征检测&#xf…

机器学习ML极简指南

机器学习是现代AI的核心&#xff0c;从推荐系统到自动驾驶&#xff0c;无处不在。但每个智能应用背后&#xff0c;都离不开那些奠基性的模型。本文用最简练的方式拆解核心机器学习模型&#xff0c;助你面试时对答如流&#xff0c;稳如老G。 线性回归 线性回归试图通过"最…

装饰器模式:如何用Java打扮一个对象?

引言装饰器模式具体实例共有接口类具体被装饰类抽象装饰器类具体装饰器类 测试装饰器模式的实际应用Java I/O 体系游戏开发中的角色装备系统 总结 引言 在生活中&#xff0c;我们都知道一句话&#xff0c;“人靠衣装马靠鞍”&#xff0c;如果想要让自己在别人眼里看起来更加好…

【Easylive】HikariCP 介绍

【Easylive】项目常见问题解答&#xff08;自用&持续更新中…&#xff09; 汇总版 HikariCP 是目前 Java 生态中最快、最轻量级的高性能 JDBC 连接池&#xff0c;被 Spring Boot 2.x 及更高版本选为 默认数据库连接池。它的名字来源于日语“光”&#xff08;Hikari&#xf…

清晰易懂的Cursor实现AI编程从安装到实战TodoList开发

一、Cursor简介与安装部署 什么是Cursor&#xff1f; Cursor是一款基于AI的智能代码编辑器&#xff0c;它集成了强大的AI编程助手功能&#xff0c;能够通过自然语言交互帮助开发者生成、优化和调试代码。与传统的代码编辑器不同&#xff0c;Cursor可以理解你的编程意图&#…

【Django】教程-2-前端-目录结构介绍

【Django】教程-1-安装创建项目目录结构介绍 3. 前端文件配置 3.1 目录介绍 在app下创建static文件夹, 是根据setting中的配置来的 STATIC_URL ‘static/’ templates目录&#xff0c;编写HTML模板&#xff08;含有模板语法&#xff0c;继承&#xff0c;{% static ‘xx’ …

注意!ChatGPT 全新 AI 图像功能延迟对免费用户开放

2025 年 3 月 25 日&#xff0c;OpenAI 正式宣布在 ChatGPT 中推出基于 GPT-4o 模型的全新原生图像生成功能。 这一功能允许用户通过对话生成和编辑图像&#xff0c;支持从写实风格到插图风格的多种形式。OpenAI 首席执行官萨姆・奥特曼&#xff08;Sam Altman&#xff09;在社…

优化webpack打包体积思路

Webpack 打包过大的问题通常会导致页面加载变慢&#xff0c;影响用户体验。可以从代码优化、依赖优化、构建优化等多个角度入手来减少打包体积&#xff1a; 代码优化 &#xff08;1&#xff09;按需加载&#xff08;代码拆分&#xff09; ① 路由懒加载 如果你的项目使用 Vu…

HarmonyOS Next~鸿蒙元服务开发指南:核心功能与实践

HarmonyOS Next&#xff5e;鸿蒙元服务开发指南&#xff1a;核心功能与实践 一、元服务核心概念 原子化服务定义 元服务&#xff08;原子服务&#xff09;是鸿蒙系统的核心架构单元&#xff0c;具备独立业务能力的轻量化服务模块&#xff0c;支持免安装、跨设备调用和智能分发…

git错误:fatal: detected dubious ownership in repository at xxxxxx

1、报错说明 这个错误通常是由于Git仓库目录的拥有者或权限问题引起的。Git检测到仓库目录的所有权可能存在不一致或不安全的情况。 通常导致此报错的可能原因&#xff1a; &#xff08;1&#xff09;文件或目录的拥有者不一致&#xff1a; 仓库目录中的某些文件或子目录可能…