Linux PipeWire深度解析之pw_main_loop_run调用流程与实战(七十四)
简介CSDN博客专家、《Android系统多媒体进阶实战》作者博主新书推荐《Android系统多媒体进阶实战》Android Audio工程师专栏地址Audio工程师进阶系列【原创干货持续更新中……】Android多媒体专栏地址多媒体系统工程师系列【原创干货持续更新中……】专题一 二AAOS车载系统AOSP14系统攻城狮入门视频实战课专题三Android14 Binder之HIDL与AIDL通信实战课专题四Android15快速自定义与集成音效实战课专题五Android15音频策略实战课专题六Android15音频性能实战课(无声/杂音/断音/爆音实战案例)人生格言人生从来没有捷径只有行动才是治疗恐惧和懒惰的唯一良药.更多原创,欢迎关注Android系统攻城狮文章目录1.前言要点概括2.应用场景与用法函数原型参数说明返回值应用场景3.调用流程剖析3.1核心步骤3.2调用流程图3.3生命周期图4.实战应用案例5.一句话总结1.前言本篇目的Linux PipeWire深度解析之pw_main_loop_run调用流程与实战。要点概括核心功能启动PipeWire主事件循环让当前线程进入阻塞式事件分发状态。工作机制内部围绕底层pw_loop反复执行事件等待和事件分发直到外部调用pw_main_loop_quit请求退出。典型用途PipeWire客户端示例程序、音频播放程序、录音程序、测试工具和常驻服务中用于驱动Core、Stream、Timer、Signal、IO等事件回调。pw_main_loop_run的本质是“事件循环入口”不是“媒体数据处理函数”。它不直接搬运PCM数据不直接执行Node Graph也不负责ALSA写入。它只是让当前线程持续等待事件并在事件就绪后调用对应回调。它和pw_main_loop_new不同。pw_main_loop_new负责创建MainLoop对象pw_main_loop_run负责让MainLoop真正跑起来。它和pw_main_loop_quit也不同run进入循环quit请求退出循环。它和pw_loop_iterate也不同pw_loop_iterate是底层单次迭代接口而pw_main_loop_run在其外层封装了持续运行逻辑。2.应用场景与用法pw_main_loop_run是PipeWire MainLoop API中用于启动主事件循环的接口。它位于PipeWire客户端程序的运行骨架中。应用创建MainLoop后可以通过pw_main_loop_get_loop取得底层pw_loop并把这个pw_loop传给pw_context_new、pw_stream_new_simple或其他事件源注册接口。完成Core连接、Stream创建、事件回调注册后应用调用pw_main_loop_run进入阻塞运行状态。pw_main_loop_run用于启动PipeWire主事件循环并持续分发事件回调。函数原型intpw_main_loop_run(structpw_main_loop*loop);参数说明structpw_main_loop*loop;loop表示已经通过pw_main_loop_new创建的PipeWire主事件循环对象。该对象内部持有底层pw_loop。应用通常不会直接操作MainLoop内部结构而是通过pw_main_loop_get_loop取得底层pw_loop用于注册Core、Stream、Timer、Signal、IO等事件源。pw_main_loop_run运行时会围绕这个底层pw_loop进行阻塞等待和事件分发。返回值成功运行并正常退出时返回整数状态值。如果底层事件循环迭代失败返回值可能携带错误状态。工程代码中通常需要检查返回值尤其是在服务类程序、测试工具和长时间运行的采集/播放程序中。需要注意pw_main_loop_run是阻塞式调用。调用后当前线程会停留在事件循环中直到调用pw_main_loop_quit或底层循环出现错误。因此它一般放在初始化流程的最后阶段。应用场景第一类场景是PipeWire客户端程序。例如播放、录音、枚举对象、监听Registry变化等程序都会先创建MainLoop再创建Core或Stream然后调用pw_main_loop_run让程序持续接收PipeWire事件。第二类场景是音频播放和录音程序。播放流中pw_main_loop_run驱动Stream的process回调触发。应用在process回调中取Buffer、填充PCM数据再提交给PipeWire。录音流中process回调被触发后应用读取采集Buffer中的PCM数据。第三类场景是测试工具和命令行Demo。很多PipeWire示例程序不需要复杂GUI事件循环只需要一个简单阻塞式MainLoop维持程序运行。pw_main_loop_run就是这类程序最常见的主循环入口。第四类场景是小型后台服务。如果服务只围绕PipeWire事件运行不需要接入GLib、Qt或其他外部事件循环可以直接使用pw_main_loop_run构建常驻进程骨架。3.调用流程剖析3.1核心步骤1.应用调用pw_main_loop_new创建MainLoop对象。2.应用调用pw_main_loop_get_loop取得底层pw_loop。3.应用基于底层pw_loop创建pw_context、pw_core、pw_stream或注册Timer、Signal、IO等事件源。4.应用完成必要的事件回调注册例如Core事件、Registry事件、Stream事件、Signal事件。5.初始化完成后应用调用pw_main_loop_run进入主事件循环。6.pw_main_loop_run进入底层Loop上下文使当前线程开始执行事件循环。7.主循环内部反复调用底层迭代逻辑等待fd、timer、signal、idle、stream等事件源就绪。8.事件源就绪后Loop分发对应回调例如Stream的process回调、Core连接状态回调、Registry全局对象回调。9.如果没有退出请求主循环继续等待下一轮事件。10.当其他回调、信号处理函数或业务逻辑调用pw_main_loop_quit后主循环停止继续迭代。11.pw_main_loop_run离开Loop上下文并把运行结果返回给调用方。12.应用随后销毁Stream、Core、Context和MainLoop等资源。3.2调用流程图3.3生命周期图4.实战应用案例下面以“创建播放Stream并运行MainLoop”为例说明pw_main_loop_run在真实PipeWire客户端程序中的位置。这个案例的重点不是播放数据本身而是主循环如何让PipeWire事件跑起来。应用创建Stream后如果不调用pw_main_loop_runCore状态变化、Stream状态变化、process回调等事件都无法持续分发程序也就不会进入稳定工作状态。#includepipewire/pipewire.hstructapp_data{structpw_main_loop*loop;structpw_stream*stream;};staticvoidon_process(void*userdata){structapp_data*datauserdata;structpw_buffer*b;bpw_stream_dequeue_buffer(data-stream);if(bNULL)return;/* * 播放流中这里通常填充PCM数据。 * 本案例只展示pw_main_loop_run所在主链路 * 具体Buffer填充逻辑可以按实际业务接入。 */pw_stream_queue_buffer(data-stream,b);}staticconststructpw_stream_eventsstream_events{PW_VERSION_STREAM_EVENTS,.processon_process,};intmain(intargc,char*argv[]){structapp_datadata{0};structpw_properties*props;pw_init(argc,argv);data.looppw_main_loop_new(NULL);if(data.loopNULL)return-1;propspw_properties_new(PW_KEY_MEDIA_TYPE,Audio,PW_KEY_MEDIA_CATEGORY,Playback,PW_KEY_MEDIA_ROLE,Music,NULL);data.streampw_stream_new_simple(pw_main_loop_get_loop(data.loop),main-loop-run-demo,props,stream_events,data);if(data.streamNULL)return-1;/* * 真实播放程序中这里还需要设置音频格式参数 * 再调用pw_stream_connect连接播放方向。 */pw_main_loop_run(data.loop);pw_stream_destroy(data.stream);pw_main_loop_destroy(data.loop);pw_deinit();return0;}在这个程序骨架中pw_main_loop_run处在初始化流程之后、资源销毁流程之前。它前面的代码负责“准备运行环境”初始化PipeWire库、创建MainLoop、创建Stream、注册Stream事件。它本身负责“保持程序运行”当前线程进入阻塞式事件循环等待PipeWire服务端事件、Stream事件和其他事件源。它后面的代码负责“退出清理”当主循环退出后销毁Stream和MainLoop并释放PipeWire全局资源。在实际工程中pw_main_loop_run最常和pw_main_loop_quit配合使用。比如收到SIGINT信号时可以在信号回调里退出主循环。#includepipewire/pipewire.hstructapp_data{structpw_main_loop*loop;structspa_source*signal;};staticvoidon_signal(void*userdata,intsignal_number){structapp_data*datauserdata;/* * 收到退出信号后不在这里直接释放复杂资源 * 只请求主循环退出。 */pw_main_loop_quit(data-loop);}这种写法的好处是退出路径清晰。信号回调只负责通知退出真正的资源释放放在pw_main_loop_run返回之后统一执行避免在回调中释放仍可能被事件循环访问的对象。需要特别注意三点。第一pw_main_loop_run是阻塞调用。它通常放在main函数初始化完成后的最后阶段。如果后续还有必须立即执行的初始化代码就不能放在run之后。第二pw_main_loop_run不等于实时媒体Graph调度。PipeWire内部可能存在数据线程、实时线程和Graph调度逻辑MainLoop主要负责客户端侧事件分发和控制事件处理。第三不要在事件回调中长时间阻塞。因为pw_main_loop_run依赖事件循环持续迭代如果某个回调长时间阻塞其他Core事件、Stream事件、Timer事件就会被延迟处理。5.一句话总结pw_main_loop_run是PipeWire客户端程序的阻塞式主事件循环入口它驱动底层pw_loop持续等待和分发事件让Core、Stream、Timer、Signal等回调真正运行直到pw_main_loop_quit请求退出。

相关新闻

DeepSeek Harness 小白入门 46:实战六:同一工作流降本,亲手提高 Cache Hit

DeepSeek Harness 小白入门 46:实战六:同一工作流降本,亲手提高 Cache Hit

DeepSeek Harness 小白入门 46:实战六:同一工作流降本,亲手提高 Cache Hit [!NOTE] 这是 第四阶段 项目实战 的第 46 课。本文面向第一次接触 Agent Harness 的读者,目标是:用前缀重排和用量对比验证优化。真实练习场景是:连续五轮对话中保持系统与工具定义稳定。全文基…

2026/8/22 13:06:26 阅读更多 →
DeepSeek Harness 小白入门 45:实战五:做一个会校验 CSV 的数据分析助手

DeepSeek Harness 小白入门 45:实战五:做一个会校验 CSV 的数据分析助手

DeepSeek Harness 小白入门 45:实战五:做一个会校验 CSV 的数据分析助手 [!NOTE] 这是 第四阶段 项目实战 的第 45 课。本文面向第一次接触 Agent Harness 的读者,目标是:将确定性数据检查交给代码,解释交给模型。真实练习场景是:检查列名、空值、重复行并输出摘要。全文…

2026/8/22 12:35:47 阅读更多 →
Java面试核心:Spring Boot与微服务架构深度解析

Java面试核心:Spring Boot与微服务架构深度解析

1. Java面试现状与核心考察点 2023年Java技术栈的面试已经形成明显的"三足鼎立"态势:Java基础(占比30%)、Spring生态(占比45%)、分布式架构(占比25%)。根据笔者参与的近百场技术面试统…

2026/8/22 11:31:59 阅读更多 →

最新新闻

数学建模核心算法:从线性回归到决策树,掌握模型选择与评估实战

数学建模核心算法:从线性回归到决策树,掌握模型选择与评估实战

1. 从“黑盒”到“白盒”:为什么你需要掌握数学建模的基本算法模型如果你参加过数学建模竞赛,或者在工作中尝试过用数据解决一个实际问题,大概率经历过这样的场景:面对一堆数据,你兴冲冲地打开某个建模软件&#xff0c…

2026/8/22 17:20:59 阅读更多 →
基于Three.js的代码仓库3D可视化:从Git数据到可交互城市

基于Three.js的代码仓库3D可视化:从Git数据到可交互城市

1. 从枯燥代码到立体城市:一个开发者的可视化奇想作为一个常年与代码打交道的开发者,我猜你和我一样,都经历过这样的时刻:面对一个庞大的、历史悠久的代码仓库,即使有再好的 IDE 和版本控制工具,那种“只见…

2026/8/22 17:20:59 阅读更多 →
区块链运维实战:从节点故障排查到智能合约管理的国赛级解析

区块链运维实战:从节点故障排查到智能合约管理的国赛级解析

1. 项目概述与赛题定位最近几年,但凡关注职业教育或者信息技术领域动态的朋友,肯定对“全国职业院校技能大赛”这个名头不陌生。它可以说是职业院校学生技能水平的“奥林匹克”,其赛题往往紧扣行业最新技术趋势和实际岗位需求,具有…

2026/8/22 17:20:59 阅读更多 →
lesson7-9计算机网络入门:从OSI七层到TCP/IP五层,一文搞懂网络分层与数据发送全过程

lesson7-9计算机网络入门:从OSI七层到TCP/IP五层,一文搞懂网络分层与数据发送全过程

Lesson 7:OSI 七层参考模型(★★★★★) 考试重要程度: ⭐⭐⭐⭐⭐一、为什么要分层? 先不要看教材。 我们先看一个生活中的例子。 假设你在淘宝买了一双鞋。 从下单到收到快递,中间有哪些人? 你…

2026/8/22 17:20:59 阅读更多 →
给 DeepSeek Harness 写了个 web UI 插件

给 DeepSeek Harness 写了个 web UI 插件

摘要:AI 编程工具的插件生态,大家都在写"工具型插件"。但想给界面换个皮肤、加只悬浮宠物,得写另一类——客户端 UI 插件。本文以我自己开源的 DSH 咸鱼宠物插件为例,拆开它的两层入口、槽位注入,以及几个踩…

2026/8/22 17:20:59 阅读更多 →
3种方式导入22个书源:阅读APP书源配置实操指南

3种方式导入22个书源:阅读APP书源配置实操指南

3种方式导入22个书源:阅读APP书源配置实操指南 【免费下载链接】Yuedu 📚「阅读」自用书源分享 项目地址: https://gitcode.com/gh_mirrors/yu/Yuedu 「阅读」APP 本身只是个解析器,装完不能直接看书,必须导入书源。本项目…

2026/8/22 17:19:54 阅读更多 →

日新闻

沉金PCB工艺实战指南:从设计到SMT焊接的可靠性保障

沉金PCB工艺实战指南:从设计到SMT焊接的可靠性保障

在电子硬件开发领域,PCB(印制电路板)的沉金工艺是提升产品可靠性和焊接质量的关键环节。对于需要高密度互连、长期稳定运行或高频信号传输的板卡,如“黍姐仿通行证”这类可能涉及身份识别、数据交互的硬件项目,选择正确…

2026/8/22 0:00:11 阅读更多 →
电气考研电路八月强化四步法:从知识体系到真题实战的闭环攻略

电气考研电路八月强化四步法:从知识体系到真题实战的闭环攻略

这次我们来看一个针对电气考研电路科目的学习规划项目。它不是软件工具,而是一套聚焦于8月份关键节点的备考策略。对于电气工程考研的同学来说,电路分析是专业课的重中之重,也是拉开分差的关键。进入8月,复习进入强化阶段&#xf…

2026/8/22 0:00:11 阅读更多 →
消除AI代码的“AI味”:Claude Code设计优化技能配置与实战指南

消除AI代码的“AI味”:Claude Code设计优化技能配置与实战指南

大家好,我是专注于前端开发与AI工具实践的技术博主。在日常使用 Claude Code 等AI编程助手时,你是否也遇到过这样的困扰:生成的代码功能上没问题,但代码风格、组件设计、交互逻辑总透着一股“AI味”——布局单调、样式简陋、交互生…

2026/8/22 0:00:11 阅读更多 →

周新闻

基于阿里云与通义千问(Qwen)构建AI应用:从模型调用到生产部署的完整实践指南

基于阿里云与通义千问(Qwen)构建AI应用:从模型调用到生产部署的完整实践指南

如果你是一名开发者,最近可能已经感受到了AI大模型正在从“玩具”变成“生产力工具”的强烈信号。从代码补全到智能Agent,从本地部署到云端API,我们正处在一个技术栈快速重构的节点。然而,面对层出不穷的模型、框架和工具&#xf…

2026/8/21 3:21:33 阅读更多 →
工业通信系统底层逻辑:04 反射——高频能量撞墙之后会发生什么?

工业通信系统底层逻辑:04 反射——高频能量撞墙之后会发生什么?

第四篇:反射——高频能量撞墙之后会发生什么? —— 你以为信号已经过去了,其实它正在回来打你 老Q的现场笔记 第五季,我们正式进入工业神经系统层。这里不再是单个设备的战斗,而是整个工厂“经脉”层面的秩序之战。从这一篇开始,你将第一次看清:看似简单的信号传播,背…

2026/8/22 8:09:09 阅读更多 →
【文章复现】非线性值迭代自适应动态规划(ADP):离散时间非线性系统的策略迭代自适应动态规划算法研究附Matlab代码

【文章复现】非线性值迭代自适应动态规划(ADP):离散时间非线性系统的策略迭代自适应动态规划算法研究附Matlab代码

✅作者简介:热爱科研的Matlab仿真开发者,擅长毕业设计辅导、数学建模、数据处理、建模仿真、程序设计、完整代码获取、论文复现及科研仿真。🍎 往期回顾关注个人主页:Matlab科研工作室👇 关注我领取海量matlab电子书和…

2026/8/21 6:07:56 阅读更多 →

月新闻

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南 【免费下载链接】BaiduNetdiskPlugin-macOS For macOS.百度网盘 破解SVIP、下载速度限制~ 项目地址: https://gitcode.com/gh_mirrors/ba/BaiduNetdiskPlugin-macOS 还在为百度网盘macOS版的龟速下…

2026/8/21 16:42:28 阅读更多 →
终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换 【免费下载链接】ncmdump 项目地址: https://gitcode.com/gh_mirrors/ncmd/ncmdump 还在为网易云音乐下载的NCM格式文件无法在其他播放器播放而烦恼吗?ncmdump解密工具帮你轻松解决这个困…

2026/8/22 7:31:03 阅读更多 →
HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

AgentCard 智能体卡片:为英语学习 App 打造桌面级学习助手适用平台:HarmonyOS 7.0 (API 26 Beta)一、引言 HarmonyOS 7.0(API 26 Beta)新增了 AgentCard 智能体卡片能力,这是继 HMAF(鸿蒙智能体框架&#x…

2026/8/22 3:22:48 阅读更多 →