Как вывести данные из потока в другой поток без блокировки? - PullRequest
0 голосов
/ 09 февраля 2009

Я разрабатываю приложение DirectShow. Я столкнулся с проблемой взаимоблокировки, которая, кажется, вызвана блокировкой получения в функции обратного вызова, вызываемой из потока. Это квест, который я задал на форуме MSDN:

http://social.msdn.microsoft.com/Forums/en-US/windowsdirectshowdevelopment/thread/f9430f17-6274-45fc-abd1-11ef14ef4c6a

Теперь я должен избегать получения блокировки в этом потоке. Но проблема в том, что я должен вывести звук в другой поток, как я могу поместить данные в другой поток без блокировки?

Кто-то сказал мне, что я могу использовать PostMessage из win32 sdk для публикации данных в другой ветке. Но, однако, чтобы получить сообщение, я должен запустить программу Windows. Моя программа представляет собой модуль расширения Python C ++. Это может быть очень трудно добавить цикл для извлечения сообщения. Так что я думаю, что другой способ передачи данных между потоками без блокировки. (На самом деле ... поток производителя не может быть заблокирован, но потребительский поток может это сделать.)

Блокировать или не блокировать, вот в чем вопрос.

Так вот вопрос, как это сделать?

Спасибо.

------ EDIT ------

Мне кажется, я знаю, почему я зашел в тупик, это может не быть проблемой DirectShow.

Основной поток принадлежит Python, он вызывает stop, а именно, содержит GIL. И остановка ожидания обратного вызова DirectShow в потоке возврата. Но обратный звонок приобретает GIL.

Это выглядит так

Main (Hold GIL) -> Stop (ожидание обратного вызова) -> Callback (Wait GIL) -> GIL (удержание в основном потоке)

Черт возьми! Вот почему я так не люблю многопоточность. Несмотря ни на что, спасибо за помощь.

Ответы [ 2 ]

1 голос
/ 09 февраля 2009

Если бы вы делали это на чистом Python, я бы использовал объект Queue; они буферизуют данные, которые записываются, но блокируются при чтении до тех пор, пока что-нибудь не станет доступно, и выполняют все необходимые блокировки под капотом.

Это очень распространенный тип данных, и всегда должен быть доступен некоторый эквивалент, независимо от вашего текущего языка или набора инструментов; например, в C ++ имеется очередь STL, но в стандарте не указываются характеристики безопасности потоков (см. документацию по локальной реализации).

0 голосов
/ 09 февраля 2009

Теоретически можно избежать блокировок, если оба ваших потока могут работать с дублирующимися копиями одних и тех же данных. Прочитав ваш вопрос на форуме MSDN ...

«Поэтому, чтобы избежать тупика, я не должен получать никакой блокировки в функции обратного вызова graber? Как я могу это сделать, если я хочу выводить звук в другой поток?»

Я думаю, что вы должны иметь возможность поместить ваши аудиоданные в очередь (класс STL), а затем извлечь эти данные из другого потока. Этот другой поток может затем обработать ваши аудиоданные.

Я рад, что ваша проблема была решена, потому что я спросил о вашей ОС, потому что в документации, на которую вы ссылались, говорилось, что вам не следует ждать в других потоках из-за проблем с win16Mutexes. В Windows XP нет win16mutexes (за исключением случаев, когда программы работают на ntvdm / wow16), поэтому вы должны иметь возможность использовать блокировки для синхронизации этих потоков.

...