2009-02-09 3 views
0

Я разрабатываю приложение 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, он вызывает остановку, а именно, он удерживает GIL. И остановка ждет обратного вызова DirectShow в потоке. Но callback приобретает GIL.

Похоже, что этот

Main (Удержание GIL) -> Stop (Ждите обратный вызов) -> Обратный вызов (Wait GIL) -> GIL (удержание на основной поток)

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

+0

Вы работаете в Windows 95/98? Если нет, то какая у вас ОС? –

+0

К сожалению, я знаю, почему он зашел в тупик. Основной поток goet GIL и остановка вызова, остановка ожидания обратного вызова и обратный вызов для GIL. –

ответ

1

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

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

+0

Да, я могу использовать STL-очередь, чтобы поместить и вытащить данные, но проблема в том, что я должен заблокировать эту очередь, прежде чем я что-то надену. Я должен избегать блокировки в потоке производителя. –

+0

FYI: Тупик возникает при вызове PyGILState_Ensure и contorl-> stop() DirectShow. Или даже PyGILState_Ensure и поиск-> Seek (...). Поэтому я думаю, что не могу получить блокировку во время обратного вызова DirectShow. –

0

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

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

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

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

+0

Является ли этот поток безопасным для ввода данных в dequeue и тянуть из другой нити? –