waveOut (Win32API) и многопоточность

Я не могу найти информацию о безопасности потоков API waveOut.

После того, как я создал новый дескриптор waveOut, у меня есть эти потоки:

Поток 1: Обработка буферов. Использует эти функции API:

  • waveOutPrepareHeader
  • waveOutWrite
  • waveOutUnprepareHeader

Нить 2: Gui, Нить контроллера. Использует эти функции API:

  • waveOutPause
  • waveOutRestart
  • waveOutReset
  • waveOutBreakLoop

Эти два потока работают при одновременном использовании одного и того же дескриптора waveOut. В своих тестах я не видел никаких проблем с функциональностью, но это не значит, что она безопасна.

Является ли эта архитектура поточно-ориентированной? Есть ли документация по безопасности потоков API waveOut? Какие-либо другие предложения по безопасности потоков API WaveOut?

Благодарю.

4 ответа

Решение

В общем случае API waveOut должен быть ориентирован на многопотоковое исполнение. Потому что обычно waveOutOpen() создает свой собственный поток, и все функции waveOut* отправляют сообщения в этот поток. Но я не могу дать вам доказательства...

Тем не менее, вы можете изменить свое приложение, чтобы сделать его безопасным в любом случае:

  1. запустите ваш поток для управления буфером, запомните dwBufferThreadId
  2. из потока графического интерфейса вызовите waveOutOpen, для которого dwCallback имеет значение dwBufferThreadId, а fdwOpen - CALLBACK_THREAD
  3. ваш поток управления буфером: "waveOutWrite" заранее несколько буферов, цикл на GetMessage ()
  4. waveOutOpen будет отправлять WOM_DONE всякий раз, когда буфер завершается и требуется новый буфер, в этот момент waveOutWrite новый буфер из этого потока
  5. Сделайте ваши вызовы waveOutPause, waveOutRestart и так далее из потока GUI (ничего в MSDN не говорит против этого, и все примеры делают это, даже если буферы будут заполнены из другого потока)

пример 1

Если вы хотите быть на 100% уверены, вы можете просто получить сообщение Windows (WM_USER+0) и позвонить PostThreadMessage( WM_USER+0, dwBufferThreadId, MY_CTL_PAUSE,0 ) а затем, получив это сообщение в буфере потока, вы вызываете waveOutPause() там. Очереди сообщений Windows избавят вас от необходимости писать собственные очереди сообщений;-)

К сожалению, это небезопасно даже в однопоточной среде. Посмотрите на этот вопрос для обсуждения:

Почему waveOutWrite() вызывает исключение в куче отладки?

Попытки сообщить об этом в Microsoft привели к закрытию ошибки. Они не собираются это исправить.

Я также не видел никакой документации, но я не могу себе представить, что вызов waveOutWrite будет считаться безопасным для одновременного выполнения с вызовом WaveOutRestart для того же дескриптора.

Если вы используете VS2010 Beta2, я бы посмотрел на различные пошаговые руководства для библиотеки агентов и попытался превратить ее в проблему потребителя производителя, когда вы передаете сообщения, такие как запись, пауза, перезапуск и т. Д.

Если вы не используете Visual Studio 2010 (или не можете), я бы посоветовал вам найти способ разбить это на проблему потребителя производителя, используя потоки и какую-то внутреннюю синхронизированную очередь, в которой хранятся команды для обработки. Если сообщения не такие частые и учитывая, что в этой очереди работают только 2 потока, вы можете избежать использования простого старого критического раздела Win32 вокруг std::queue...

надеюсь это поможет.

Это может быть потокобезопасным, но если вы (или я) не можете найти официальную документацию, утверждающую, что это потокобезопасный, то предположите, что это не так и добавьте свою собственную синхронизацию потоков. Легкая реализация EnterCriticalSection / LeaveCriticalSection, вероятно, занимает не более десятка строк кода.

Никакое количество испытаний не может гарантировать, что API является поточно-ориентированным: проблемы могут возникать только на некоторых архитектурах с некоторыми скоростями процессора или шины или с некоторыми звуковыми картами. Ни у вас (ни у Microsoft) нет возможности протестировать все возможные конфигурации.

Вы также не должны делать никаких предположений о том, что Microsoft или Intel, или производитель звуковых карт, или драйвер будут делать в будущем.

Другие вопросы по тегам