waveInReset/waveOutReset死锁原因与解决方案

简介:

问题背景

 

录音播音实际需求

1、随时终止

2、录音并非文件,而是形成rtp发送

3、播音并非源于文件,而是源于rtp

 

因此Waveform audio使用的buffer较小,不断的装载/发送 buffer,终止的时候Reset并且close.

大致如下调用的循环

 

录音

waveInUnprepareHeader

waveInPrepareHeader

waveInAddBuffer

 

播音

waveOutUnprepareHeader

waveOutPrepareHeader

waveOutWrite

 

循环周期40ms,我采用的是回调函数。问题是有时候调用waveInReset/waveOutReset会形成死锁,调用waveInReset/waveOutReset的线程与回调函数所在的线程死锁在一块了。

 

原因分析

这方面网上有文章提到,就是调用waveInReset/waveOutReset的同时调用了录音/播音循环调用的某个函数会形成死锁。我再稍作解释下,我们知道buffer满了或是调用Reset都会触发消息(回调函数方式的话就是MM_WOM_DONE/MM_WIM_DATA),由于调用waveInReset/waveOutReset所在的线程,与回调函数所在的线程不是一个线程,因此很容易撞车,也就是说,你调用reset的时候,另一个线程正好在处理MM_WOM_DONE/MM_WIM_DATA,于是就这样死锁了。

 

解决方案

方案一

先加上标记(假设标记bReset:bool),令bReset为true;

 

标记作用如下

if(!bReset)

{

录音

waveInUnprepareHeader

waveInPrepareHeader

waveInAddBuffer

 

播音

waveOutUnprepareHeader

waveOutPrepareHeader

waveOutWrite

}

延时调用waveInReset/waveOutReset,延时时间长度以循环周期为妙,我这个例子中也就是采用40ms。

 

当然也可以采用临界保护。


方案二

换一个角度去考虑问题,之所以死锁,是因为两个线程冲突了的缘故,所以可以建立一个线程

录音

waveInUnprepareHeader

waveInPrepareHeader

waveInAddBuffer

 

播音

waveOutUnprepareHeader

waveOutPrepareHeader

waveOutWrite

 

与waveInReset/waveOutReset都放到这个线程去处理,自然不会发生死锁了。

目录
相关文章
|
人工智能 大数据 数据处理
【开源项目推荐】8.9K纯中文本地GPT知识库搭建项目
【开源项目推荐】8.9K纯中文本地GPT知识库搭建项目
1583 57
|
安全 项目管理
一文搞懂需求流程规范的制定方法和落地技巧
随着业务和产品的发展、团队的不断扩大,很多团队都不可避免的会遇到需求流程混乱的问题。虽然有的团队也编写了一些“需求流程规范”的文档,但最终却流于纸面,难以在团队真正落地。如何科学制定并有效落实需求管理规范呢?对此,云效产品经理陈逊进行了非常详细的直播分享,本文是他经验的文字总结。
103516 19
|
关系型数据库 Linux Apache
|
图形学
【制作100个unity游戏之28】花半天时间用unity复刻童年4399经典小游戏《黄金矿工》(附带项目源码)
【制作100个unity游戏之28】花半天时间用unity复刻童年4399经典小游戏《黄金矿工》(附带项目源码)
565 0
|
10月前
|
Java 调度
Java 线程同步的四种方式,最全详解,建议收藏!
本文详细解析了Java线程同步的四种方式:synchronized关键字、ReentrantLock、原子变量和ThreadLocal,通过实例代码和对比分析,帮助你深入理解线程同步机制。关注【mikechen的互联网架构】,10年+BAT架构经验倾囊相授。
Java 线程同步的四种方式,最全详解,建议收藏!
|
缓存 Cloud Native 区块链
重塑链上数据索引,Chainbase 云原生 Subgraph 解析
Subgraph 是 The Graph 去中心化应用索引协议的具体实现, 能为各个智能合约创建索引引擎,提供 dataset 数据集供开发者快速查询使用。目前,Chainbase 正式上线并托管的核心 dataset subgraph 数量已经超过 100+。
719 0
重塑链上数据索引,Chainbase 云原生 Subgraph 解析
|
网络协议 网络架构
网络工程师如何配置6to4隧道解决IPv6过渡问题(含动图)?
网络工程师如何配置6to4隧道解决IPv6过渡问题(含动图)?
853 0
|
Web App开发 存储 算法
|
并行计算 算法 安全
[Eigen中文文档] Eigen 和多线程
某些 Eigen 算法可以利用硬件中存在的多个内核。
773 0
|
算法 API Windows
借用PortAudio采集和播放音频,实现双路混音器
借用PortAudio采集和播放音频,实现双路混音器
417 0