如果捕获VK_ESCAPE
键,我想从另一个线程停止主线程,并在用户按任意键时恢复主线程。
我打算构造“ThreadProc1”线程来捕获按下的键:
DWORD WINAPI ThreadProc1(LPVOID param){
while(1){
if(GetAsyncKeyState(VK_ESCAPE)){
//Stop the main thread
}
}
}
答案 0 :(得分:1)
不要那样做。要么:1)当主线程从Esc键接收到消息时再次按下该消息,直到再次按下该消息时,使主线程跳过所有有意义的动作。 2)使用CreateEvent并在其上放置主线程WaitForMultipleObjects,然后从其他线程使用SetEvent唤醒它,或者在超时时将其唤醒。
主线程如果启动消息泵,则是Windows应用程序的“心脏和大脑”,停止它相当于临床死亡。可以返回的“阻塞”动作,如从文件,套接字等中读取,是合法的,其他线程不会因死锁而导致。睡觉是合法的,因为线程可以被唤醒。将消息泵线程置于睡眠状态而不替代消息泵是可疑的行为,这种应用可能被认为是“挂起”。停止的驱动程序将被杀死,服务无限期挂起,桌面GUI将提供用户停止应用程序(或将在企业环境中停止该应用程序,如果管理员是偏执的),并将在任务栏中标记它“没有响应“等等。
答案 1 :(得分:1)
正式暂停线程非常简单 - SuspendThread
然后ResumeThread
- 但是:
此功能主要供调试器使用。它不是 旨在用于线程同步。调用SuspendThread 在拥有同步对象的线程上,例如互斥锁或 临界区,如果调用线程尝试,可能导致死锁 获取被挂起的线程拥有的同步对象。至 避免这种情况,应用程序中的一个线程不是 调试器应该通知另一个线程暂停自己。目标 线程必须设计为观察此信号并做出响应 适当。
很可能在挂起时由线程调用(HeapAlloc
或HeapFree
(并且它经常在Windows消息处理上调用)。和线程保持堆临界区。如果在此之后工作线程也直接或间接(非常高的可能性)调用HeapAlloc
(或同一堆的任何其他堆函数 - 通常这是主进程堆) - 你遇到了死锁。
你当然可以说发送一些带有事件句柄的已知消息给主线程 - 主线程将等待事件,直到工作线程没有调用SetEvent
- 但这也是坏的而不是质量解决方案。
UI线程一定不能阻塞等待,永久等待Windows消息。我不知道您尝试执行哪项任务,但100%确定现有解决方案,而不会阻止UI线程