2015-11-05 6 views
0

Некоторые фон, если вы заинтересованы, в противном случае вы можете пойти прямо на вопрос в нижней части:WaitForSingleObject Тупик

Я бегу на вопрос, где я есть бесконечный while цикл с двумя if условия проверки на два события объектные состояния становятся сигнальными.

while(1) 
{ 
    if(DAQ_Comm_Server::usb_detect_flag == false) 
    { 
     if(WaitForSingleObject(USB_PHY_CONN,INFINITE) == WAIT_OBJECT_0) 
     { 
      DAQ_Comm_Server::usb_detect_flag = true; 
     } 
    } 

    if(DAQ_Comm_Server::usb_detect_flag == true) 
    { 
     if(WaitForSingleObject(USB_PHY_DISCONN, INFINITE) == NULL) 
     { 
      DAQ_Comm_Server::usb_detect_flag = false; 
     } 
    } 
} 

объекты USB_PHY_CONN События и USB_PHY_DISCONN Создаются в моем OS/БСПЕ коде драйвера USB, где он обнаружит подключение аппаратного USB и продолжить использовать SetEvent() установить соответствующий объект события.

Чтение документации для WaitForSingleObject(), в нем явно не указано, что она должна использоваться внутри потока, хотя после прочтения ее несколько раз я чувствую, что это подразумевается, но im не на 100% уверен.

Проблема, с которой я столкнулась, - это первый раз, когда код проходит через цикл while (то есть, usb изначально отключен, затем подключен и отключен), моя система работает нормально и не зависает. Однако при повторном подключении USB моя система зависает. Мое устройство перестает отвечать/UI замерзает, и код теряется.

Теперь, когда я убью процесс, в котором находится приведенный выше код, все начинает резервное копирование и продолжает работать нормально. Я сделал некоторое чтение, и кажется, что WaitForSingleObject() рискует иметь возможный тупик, но я также заметил, что он всегда с точки зрения потоков.

Мой вопрос:, does WaitForSingleObject() Идём использовать в потоке? Если я использую его в бесконечном цикле в основном, это приводит к высокому риску блокировки/блокировки системы?

Примечание. Это встроенный в платформу встроенный проект CE 7 с VS2008.

+3

Если вы используете 'WaitForSingleObject' в потоке пользовательского интерфейса, то обработка сообщений прекратится, и система будет потенциально рассматривать ваше окно как невосприимчивое. Посмотрите на 'MsgWaitForMultipleObjects' вместо этого. –

+0

И если у вас есть только поток от 'main', который должен логически быть вашим потоком пользовательского интерфейса. (Windows позволяет использовать поток _any_ в качестве потока пользовательского интерфейса, не обязательно должен быть потоком 'main'. Если вам нравится жить опасно, вы можете даже иметь один поток пользовательского интерфейса _per window_!) – MSalters

+0

@MSalters My UI thread is в другом процессе. – Javia1492

ответ

1

Вы не можете выполнить код снаружи нить! Существует «основная» нить, которая начинается с main, но это тоже поток, как и любой другой.

Тем не менее, для взаимоблокировки требуются 2 потока и 2 точки синхронизации. Один поток блокирует A, другой поток блокирует B, а затем оба потока блокируются, когда они пытаются получить другой замок.

Это может быть решительно устранено путем заказа замка. Если блокировка A равна всегда заблокирована до B, то между потоками, которые имеют A и другие потоки, которые имеют блокировку B., не возникает взаимоблокировка.

Более теоретический подход доказывает, что проблема представляет собой цикл на графике блокировки. Цикл A < => B - простейший цикл длины 2. A-> B-> C-> A также может зайти в тупик. Направленный ациклический график заказов блокировки соответствует программе без взаимоблокировок.

+0

И, как всегда, [Не забудьте включить очередь сообщений в иерархию блокировки] (http://blogs.msdn.com/b/oldnewthing/archive/2011/04/18/10154966.aspx). – IInspectable

+0

Итак, я не понял, что мой главный будет функционировать как поток. – Javia1492

+1

@ Javia1492: Основная нить не * "function" * как нить. Это ** есть ** [поток] (https://en.wikipedia.org/wiki/Thread_ (вычисления)). Вы никогда не сможете запускать код за пределами потока. – IInspectable

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