2009-12-09 4 views
3

Я не могу найти информацию о безопасности потоков для waveOut API.waveOut (Win32API) и многопоточность

После того как я создание нового WaveOut ручки, у меня есть такие темы:

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

  • waveOutPrepareHeader
  • waveOutWrite
  • waveOutUnprepareHeader

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

  • waveOutPause
  • waveOutRestart
  • waveOutReset
  • waveOutBreakLoop

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

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

спасибо.

+0

Вы должны прочитать это, прежде чем внедрять что-либо с помощью API waveOut: http://stackoverflow.com/questions/195696/why-would-waveoutwrite-cause-an-exception-in-the-debug-heap –

ответ

4

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

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

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

example 1

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

+0

, если вы используете некоторые переменные, чтобы отслеживать количество используемых буферов, - это хорошая идея поместить на них блокировку обмена (обратный вызов с приоритетом) и добавить восстановление из нижнего уровня буфера (иногда может возникать недостаточное количество потоков с небольшой конфигурацией задержки), это всегда срабатывало для моей многопоточной программ ... и также устранить этот шум с черепом/сбой – Spektre

+0

Вы не можете использовать WM_USER + 0: waveOutOpen(), waveOutWrite() и т. д. по какой-либо причине отправляют WM_USER + 0 (1024) в GetMessage() , в дополнение к сообщениям, которые они документируют как отправку. –

2

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

Если вы используете VS2010 Beta2 Я хотел бы посмотреть на различных прохождений для Agents Library и попытаться превратить это в проблему производитель потребительской где вы передаете сообщения как записи, пауза, перезагрузка и т.д.

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

Надежда это помогает.

1

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

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

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

2

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

Why would waveOutWrite() cause an exception in the debug heap?

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

Смежные вопросы