2016-12-09 1 views
-4

Я хочу остановить основной поток из другого потока, если захвачен VK_ESCAPE и возобновить основной поток, когда пользователь нажимает любую клавишу. я намерен построить «ThreadProc1» нить поймать нажимается клавиша:Как остановить основную нить из другого потока в c/C++

DWORD WINAPI ThreadProc1(LPVOID param){ 
    while(1){ 
     if(GetAsyncKeyState(VK_ESCAPE)){ 
      //Stop the main thread 
     } 
    } 
} 
+0

Главный поток не может быть остановлен без выхода из программы – TomJ

+2

Вы хотите, чтобы вы * убивали * нить, или просто * suspend * it? –

+5

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

ответ

1

Не делай этого. Либо: 1) Сделать основной поток, чтобы пропустить все значимые действия, когда он получает сообщение от клавиши Esc, нажатой до тех пор, пока он не будет нажат снова. 2) Используйте CreateEvent и нанесите основной поток WaitForMultipleObjects на него, а затем разбудите его с помощью SetEvent из другого потока или в таймаут.

Первичная нить, если она была запущена насосом для сообщений, является «сердцем и мозгом» приложения Windows, поэтому его остановка эквивалентна клинической смерти. «блокирующие» действия, из которых можно вернуться, например, чтение из файла, сокеты и т. д., являются законными, предполагал, что другой поток не вызвал бы тупик. Сон закончен, потому что поток можно разбудить. Ввод сообщения нить насоса в сон без замены для сообщения насоса - это действие сомнительной добродетели, такое применение может считаться «зависающим». драйверы, которые остановились, будут убиты таким образом, службы будут висели на неопределенное время, графический интерфейс рабочего стола предложит пользователю остановить приложение (или остановит это приложение в корпоративной среде, если админы были параноидальными) и отметит его на панели задач «не отвечает» »и т.д.

+0

Приложения Windows не имеют понятия * "основного потока" *. Существует * «первичный поток» *, но это только ваш средний поток, у которого только отличительная особенность, что он был первым, созданным в процессе. Блокирование первичной нити не оказывает неблагоприятного воздействия (если только этот поток не владеет графическим интерфейсом). 'WaitForSingleObject' ** делает ** блок, и, хотя законно его вызывать из потока GUI, это приведет к зависанию графического интерфейса. [MsgWaitForMultipleObjects] (https://msdn.microsoft.com/en-us/library/windows/desktop/ms684242.aspx) - лучший вариант (даже если это сложно использовать). – IInspectable

+2

С вероятностью> 0.999 первый созданный поток представляет собой поток GUI –

+0

@DavidHeffernan: Разработка программного обеспечения не является упражнением в статистике. Кроме того, 99,9% всей статистики составлено из воздуха. – IInspectable

1

формально приостановить поток очень легко - SuspendThread, а затем ResumeThread - но:

Эта функция предназначена главным образом для использования отладчиков. Это не , предназначенное для синхронизации потоков. Вызов SuspendThread в потоке, которому принадлежит объект синхронизации, например критический раздел mutex или , может привести к тупиковой ситуации, если вызывающий поток пытается выполнить , чтобы получить объект синхронизации, принадлежащий приостановленному потоку. В избежать этой ситуации, поток в приложении, который не является отладчиком , должен сигнализировать о том, что другой поток приостанавливается. Целевая линия должна быть спроектирована так, чтобы следить за этим сигналом и отвечать соответствующим образом .

вполне вероятный сценарий - HeapAlloc или HeapFree называется (и это часто называют по обработке окна сообщений) ниткой на приостановить время. и критический участок кучи резьбы. если рабочий поток после этого также прямой или косвенный (очень высокая вероятность этого) вызывает HeapAlloc (или любую другую функцию кучи для той же кучи - обычно это основная куча процесса) - вы зашли в тупик.

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

UI thread не должен блокировать ожидание вообще, постоянное ожидание сообщений Windows. я точно не знаю, какую задачу вы выполняете, но на 100% уверен, что существует решение без блокировки нити пользовательского интерфейса на всех