Linux PipeWire深度解析之pw_thread_loop_new_full调用流程与实战(十五)

📅 2026/7/19 18:03:14 👁️ 阅读次数 📝 编程学习
Linux PipeWire深度解析之pw_thread_loop_new_full调用流程与实战(十五)

简介:CSDN博客专家、《Android系统多媒体进阶实战》作者

博主新书推荐:《Android系统多媒体进阶实战》🚀
Android Audio工程师专栏地址:Audio工程师进阶系列原创干货持续更新中……】🚀
Android多媒体专栏地址:多媒体系统工程师系列原创干货持续更新中……】🚀
专题一 二:AAOS车载系统+AOSP14系统攻城狮入门视频实战课🚀
专题三:Android14 Binder之HIDL与AIDL通信实战课🚀
专题四:Android15快速自定义与集成音效实战课🚀
专题五:Android15音频策略实战课🚀
专题六:Android15音频性能实战课(无声/杂音/断音/爆音实战案例)🚀

人生格言:人生从来没有捷径,只有行动才是治疗恐惧和懒惰的唯一良药.

更多原创,欢迎关注:Android系统攻城狮


🍉🍉🍉文章目录🍉🍉🍉

  • 🌻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;当loopNULL时,内部自动创建新的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

当传入的loopNULL时,接口会自动创建新的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);

也可以不提前创建,直接传入:

NULL

2. 调用 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

当参数loopNULL时:

调用 pw_loop_new(props) 创建新的 pw_loop

PipeWire 内部会记录这个 Loop 是否由 Thread Loop 自己创建,从而决定销毁 Thread Loop 时是否同时销毁底层 Loop。(GitHub)


5. 设置 Loop 名称

内部根据name参数设置底层 Loop 名称。

name不为NULL时:

使用应用指定的名称

nameNULL时:

使用默认名称 thread-loop

6. 初始化 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 管理和多线程事件处理中的基础创建接口。