2009-12-09 85 views
3

我找不到关于waveOut API线程安全性的任何信息。waveOut(Win32API)和多线程

我创造新的waveout的手柄后,我有这些线程:

主题1:缓冲处理。使用这些API函数:

  • waveOutPrepareHeader
  • waveOutWrite
  • waveOutUnprepareHeader

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

  • waveOutPause
  • waveOutRestart
  • waveOutReset
  • waveOutBreakLoop

这两个线程都在使用的同时同waveout的手柄运行。 在我的测试中,我没有看到任何功能问题,但并不意味着它是安全的。

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

谢谢。

+0

您应该在使用waveOut API执行任何操作之前阅读此内容:http://stackoverflow.com/questions/195696/why-would-waveoutwrite-cause-an-exception-in-the-debug-heap – 2009-12-18 23:33:11

回答

4

一般来说,waveOut API应该是线程安全的。因为通常waveOutOpen()会创建自己的线程,所有waveOut *函数都会将消息发送到该线程。但我不能给你一个证明......

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

  1. 启动缓冲器管理线程,从GUI线程调用记得dwBufferThreadId
  2. waveOutOpen with dwCallback设置为dwBufferThreadId和fdwOpen到CALLBACK_THREAD
  3. 您的缓冲区管理线程:“waveOutWrite”提前一些缓冲区,GetMessage循环()
  4. waveOutOpen将发送一个WOM_DONE,只要缓冲区完成并且需要一个新的缓冲区,这是瞬间从该线程中waveOutWrite一个新的缓冲区
  5. 作出waveOutPause,waveOutRestart您的通话等从GUI线程(没有在MSDN说反对的话,所有的例子做到这一点,即使缓冲区将从另一个充满线)

example 1

如果你想成为100%的把握,你可以只抓住一个窗口消息(WM_USER + 0),并调用PostThreadMessage(WM_USER+0, dwBufferThreadId, MY_CTL_PAUSE,0),然后根据你的缓冲线程接收消息,您在那里拨打waveOutPause()。 Windows消息队列为您节省了一些编写自己的消息队列的工作;-)

+0

如果您使用有些变量需要跟踪已用缓冲区的数量,因此将共享锁定(回调具有优先级)放在它们上面并从缓冲区下溢中添加恢复(下溢有时可能发生在小延迟配置下)是一个好主意,这对我的多线程程序...并且还消除了这种混淆/干扰噪音 – Spektre 2013-09-20 14:02:16

+0

你不能使用WM_USER + 0:由于某种原因,waveOutOpen(),waveOutWrite()等正在向我的音频线程的GetMessage()发送WM_USER + 0(1024) ,除了它们被记录为发送的消息之外。 – 2016-03-25 16:32:36

2

我没有看到任何文档,但我无法想象对waveOutWrite的调用将被认为是安全的,可以在同一个句柄上同时调用WaveOutRestart。

如果你使用VS2010 Beta2中我会看各种的演练为Agents Library,并试图把它变成你在哪里传递消息像写,暂停,重新开始一个生产者消费者问题,等等

如果你没有使用Visual Studio 2010(或者不能)我鼓励你找到一种方法将它分解成生产者消费者问题,使用线程和某种内部同步队列来存储命令进行处理。如果消息不是那么频繁,并且假设你只有2个线程在这个队列上工作,那么你可以在std ::队列周围放置一个普通的旧Win32临界区...

hope这有助于。

1

它可能是线程安全的,但如果您(或我)找不到任何官方文档说明它是线程安全的,那么假设它不是' t并添加您自己的线程同步。轻量级的EnterCriticalSection/LeaveCriticalSection实现可能不超过十几行代码。

没有任何测试可以向您保证API是线程安全的:问题可能只发生在某些CPU或总线速度或某些声卡的架构上。你(不是微软)都没有能力测试所有可能的配置。

你也应该不会做出什么微软或英特尔或声卡制造商或驱动程序编写者将在未来的某个实现做任何假设。