Linux PipeWire深度解析之pw_thread_loop_new_full调用流程与实战(十五)
简介:CSDN博客专家、《Android系统多媒体进阶实战》作者
博主新书推荐:《Android系统多媒体进阶实战》🚀
Android Audio工程师专栏地址:Audio工程师进阶系列【原创干货持续更新中……】🚀
Android多媒体专栏地址:多媒体系统工程师系列【原创干货持续更新中……】🚀
专题一 二:AAOS车载系统+AOSP14系统攻城狮入门视频实战课🚀
专题三:Android14 Binder之HIDL与AIDL通信实战课🚀
专题四:Android15快速自定义与集成音效实战课🚀
专题五:Android15音频策略实战课🚀
专题六:Android15音频性能实战课(无声/杂音/断音/爆音实战案例)🚀
人生格言:人生从来没有捷径,只有行动才是治疗恐惧和懒惰的唯一良药.
🍉🍉🍉文章目录🍉🍉🍉
- 🌻1. 前言
- 要点概括
- 🌻2. 应用场景与用法
- 函数原型
- 参数说明
- 返回值
- 应用场景
- 🌻3. 调用流程剖析
- 🌻3.1 核心步骤
- 1. 准备底层 pw_loop
- 2. 调用 pw_thread_loop_new_full
- 3. 分配 Thread Loop 管理对象
- 4. 处理底层 Loop
- 5. 设置 Loop 名称
- 6. 初始化 Listener 管理结构
- 7. 返回 pw_thread_loop
- 8. 启动 Thread Loop
- 🌻3.2 调用流程图
- 🌻3.3 Thread Loop创建生命周期图
- 🌻4. 实战应用案例
- 🌻5. 一句话总结
🌻1. 前言
本篇目的:
Linux PipeWire 深度解析之pw_thread_loop_new_full调用流程与实战。
要点概括
- 核心功能:使用指定的
pw_loop创建一个pw_thread_loop对象。 - 工作机制:接口创建 Thread Loop 管理对象,保存线程名称和属性,并封装传入的底层
pw_loop;当loop为NULL时,内部自动创建新的pw_loop。 - 典型用途:复用自定义 Loop、独立线程运行事件循环、PipeWire Core 管理、Stream 异步控制。
pw_thread_loop_new_full()只完成 Thread Loop 对象创建,不会立即启动工作线程。创建成功后,需要调用pw_thread_loop_start()才会启动线程并运行底层事件循环。(PipeWire)
🌻2. 应用场景与用法
pw_thread_loop_new_full()是 PipeWire Thread Loop 创建体系中的完整构造接口。
普通的:
pw_thread_loop_new(name,props);由 Thread Loop 内部自动创建底层pw_loop。
而:
pw_thread_loop_new_full(loop,name,props);允许应用传入一个已经创建的pw_loop,再由 Thread Loop 对该 Loop 进行线程化封装。
该接口用于:
使用指定的底层
pw_loop、线程名称和属性创建pw_thread_loop。
当传入的loop为NULL时,接口会自动创建新的pw_loop;当传入已有pw_loop时,Thread Loop 直接封装并复用该对象。(PipeWire)
函数原型
structpw_thread_loop*pw_thread_loop_new_full(structpw_loop*loop,constchar*name,conststructspa_dict*props);参数说明
loop:需要封装的底层 pw_loop 传入已有 pw_loop:复用应用创建的 Loop 传入NULL:内部自动创建新的 pw_loop name:Thread Loop 对应的线程名称 可以传入NULLprops:Thread Loop 属性字典 不需要额外属性时可以传入NULL返回值
成功:返回新创建的 pw_thread_loop 指针 失败:返回NULL返回成功仅表示 Thread Loop 对象创建完成,此时工作线程尚未启动。
应用场景
pw_thread_loop_new_full()常见应用场景主要有三类。
第一类是复用应用已经创建的pw_loop。应用可能已经通过pw_loop_new()创建底层 Loop,并注册了 I/O、Timer、Signal、Event 等事件源。此时可以把已有 Loop 传给pw_thread_loop_new_full(),让该 Loop 后续运行在独立线程中。
第二类是自定义 Thread Loop 属性。应用可以通过props传入线程相关属性,再为 Thread Loop 指定清晰的线程名称,便于日志分析、线程调试和多实例管理。
第三类是 PipeWire Core 和 Stream 的异步管理。应用可以先创建并封装底层 Loop,再获取pw_thread_loop_get_loop()返回的pw_loop,用于创建pw_context、连接pw_core、创建pw_stream和注册事件回调,最后调用pw_thread_loop_start()启动事件线程。
🌻3. 调用流程剖析
🌻3.1 核心步骤
1. 准备底层 pw_loop
应用可以先创建一个底层 Loop:
structpw_loop*loop;loop=pw_loop_new(NULL);也可以不提前创建,直接传入:
NULL2. 调用 pw_thread_loop_new_full
应用执行:
structpw_thread_loop*thread_loop;thread_loop=pw_thread_loop_new_full(loop,"pipewire-thread-loop",NULL);3. 分配 Thread Loop 管理对象
接口内部为:
structpw_thread_loop分配内存,用于保存底层 Loop、线程句柄、运行状态和 Listener 等信息。
4. 处理底层 Loop
当参数loop不为NULL时:
直接保存并封装已有 pw_loop当参数loop为NULL时:
调用 pw_loop_new(props) 创建新的 pw_loopPipeWire 内部会记录这个 Loop 是否由 Thread Loop 自己创建,从而决定销毁 Thread Loop 时是否同时销毁底层 Loop。(GitHub)
5. 设置 Loop 名称
内部根据name参数设置底层 Loop 名称。
当name不为NULL时:
使用应用指定的名称当name为NULL时:
使用默认名称 thread-loop6. 初始化 Listener 管理结构
接口初始化 Thread Loop 内部的 Listener List,为后续:
pw_thread_loop_add_listener()注册销毁等事件回调做准备。
7. 返回 pw_thread_loop
创建成功后返回:
structpw_thread_loop*此时只完成对象和同步运行环境的准备,工作线程尚未启动。
8. 启动 Thread Loop
后续调用:
pw_thread_loop_start(thread_loop);PipeWire 创建工作线程,在线程中执行:
pw_loop_enter() pw_loop_iterate() pw_loop_leave()从而让底层pw_loop在独立线程中持续运行。(PipeWire)
🌻3.2 调用流程图
🌻3.3 Thread Loop创建生命周期图
🌻4. 实战应用案例
#include<pipewire/pipewire.h>// PipeWire核心API#include<stdio.h>#include<stdlib.h>structapp_data{structpw_loop*loop;// 应用创建的底层Loopstructpw_thread_loop*thread_loop;// Thread Loop管理对象};intmain(intargc,char*argv[]){structapp_datadata={0};intresult;pw_init(&argc,&argv);// 初始化PipeWire环境data.loop=pw_loop_new(NULL);// 创建底层pw_loopif(!data.loop){fprintf(stderr,"pw_loop_new failed\n");pw_deinit();returnEXIT_FAILURE;}data.thread_loop=pw_thread_loop_new_full(data.loop,"pipewire-worker",NULL);// 使用已有pw_loop创建Thread Loopif(!data.thread_loop){fprintf(stderr,"pw_thread_loop_new_full failed\n");pw_loop_destroy(data.loop);pw_deinit();returnEXIT_FAILURE;}result=pw_thread_loop_start(data.thread_loop);// 启动独立事件线程if(result<0){fprintf(stderr,"pw_thread_loop_start failed: %d\n",result);pw_thread_loop_destroy(data.thread_loop);pw_loop_destroy(data.loop);pw_deinit();returnEXIT_FAILURE;}pw_thread_loop_lock(data.thread_loop);// 获取Loop互斥锁/* * 在临界区内可以安全执行: * * pw_context_new() * pw_context_connect() * pw_stream_new() * pw_stream_connect() */pw_thread_loop_unlock(data.thread_loop);// 释放Loop互斥锁pw_thread_loop_stop(data.thread_loop);// 停止工作线程pw_thread_loop_destroy(data.thread_loop);// 销毁Thread Loop封装对象pw_loop_destroy(data.loop);// 销毁应用创建的底层pw_looppw_deinit();// 释放PipeWire资源returnEXIT_SUCCESS;}🌻5. 一句话总结
pw_thread_loop_new_full()本质上是:
“使用指定的
pw_loop、线程名称和属性,创建一个能够在独立线程中运行该 Loop 的pw_thread_loop对象”。
它负责完成底层 Loop 封装、Thread Loop 对象分配、名称设置和运行环境初始化,但不会立即启动线程,是自定义 PipeWire Loop、Core 异步通信、Stream 管理和多线程事件处理中的基础创建接口。
