waveOut (Win32API) 和多线程

DxC*_*xCK 3 audio winapi multithreading thread-safety waveout

我找不到任何有关 waveOut API 线程安全性的信息。

创建新的 waveOut 句柄后,我有这些线程:

线程 1:缓冲区处理。使用这些 API 函数:

  • 波输出准备标头
  • 波输出写
  • waveOutUnprepareHeader

线程2:Gui,控制器线程。使用这些 API 函数:

  • 挥手暂停
  • 波出重启
  • 波输出复位
  • 波出断环

这两个线程在同时使用相同的 waveOut 句柄时运行。在我的测试中,我没有发现功能有任何问题,但这并不意味着它是安全的。

这个架构是线程安全的吗?有没有关于waveOut API 线程安全的文档?关于 waveOut API 线程安全性还有其他建议吗?

谢谢。

Fru*_*nsi 5

一般来说,waveOut API 应该是线程安全的。因为通常 waveOutOpen() 会创建自己的线程,并且所有 waveOut* 函数都会向该线程发送消息。但我无法给你证据...

但是,您可以更改您的应用程序以使其在任何情况下都安全:

  1. 启动线程进行缓冲区管理,记住 dwBufferThreadId
  2. 从GUI线程调用waveOutOpen,dwCallback设置为dwBufferThreadId,fdwOpen设置为CALLBACK_THREAD
  3. 您的缓冲区管理线程:提前“waveOutWrite”一些缓冲区,GetMessage() 上的循环
  4. 每当缓冲区完成并且需要新缓冲区时,waveOutOpen 将发送 WOM_DONE,这是从该线程内 waveOutWrite 一个新缓冲区的时刻
  5. 从 GUI 线程调用 waveOutPause、waveOutRestart 等(MSDN 中没有任何内容反对它,所有示例都这样做,即使缓冲区将从另一个线程填充)

示例1

如果你想 100% 确定,你可以抓取一条 Windows 消息 (WM_USER+0),然后调用PostThreadMessage( WM_USER+0, dwBufferThreadId, MY_CTL_PAUSE,0 ),然后在缓冲线程中收到该消息后,你就waveOutPause()在那里调用。Windows 消息队列为您节省了一些编写自己的消息队列的工作;-)