主线程中慎用WaitForSingleObject (WaitForMultipleObjects)

主线程中慎用WaitForSingleObject (WaitForMultipleObjects)

下面的代码我调试了将近一个星期,你能够看出什么地方出了问题吗?

线程函数:

 DWORD WINAPI ThreadProc(

    while(!bTerminate)

    {

        // 从一个链表中读取信息并且插入到CListCtrl

        // CListCtrl的句柄是通过线程参数传递进来的

        for(;;)

       {

           ReadInfoFromList();

           InsertToCListCtrl();

        }

    }

}

主线程中使用CreateThread启动线程。

当想终止子线程时,在主线程中:

bTerminate = TRUE;

WaitForSingleObject(threadHandle, INFINITE);

可是,一运行到WaitForSingleObject,子线程就Crash了。

为什么呢?

后来我终于在InsertItem的反汇编中发现了如下的代码:

call dword ptr [__imp__SendMessageA@16 (7C141B54h)]

可见,InsertItem是必须借助消息循环来完成任务的。如果我们在主线程中WaitForSingleObject了,必然导致主线程阻塞,也就导致了消息循环的阻塞,最终导致工作线程Crash掉了。

解决方案:

为了解决在主线程中Wait的问题,微软专门设计了一个函数MsgWaitForMultipleObjects,这个函数即可以等待信号(thread,event,mutex等等),也可以等待消息(MSG)。即不论有信号被激发或者有消息到来,此函数都可以返回。呵呵,那么我的解决办法也就出来了。

将上面的WaitForSingleObject用下面的代码替换:

while(TRUE)

{

 

    DWORD result ;

    MSG msg ;

 

    result = MsgWaitForMultipleObjects(1, &readThreadHandle, FALSE, INFINITE, QS_ALLINPUT);

    if (result == (WAIT_OBJECT_0))

    {

        break;

    }

    else

    {

        PeekMessage(&msg, NULL, 0, 0, PM_REMOVE);

        DispatchMessage(&msg);

    }

}

总结:

如果在工作线程中有可能涉及到了消息驱动的API,那么不能在主线程中使用WaitForSingleObject一类函数,而必须使用上述的方案。

【转载】https://www.cnblogs.com/shootingstars/archive/2004/07/15/24602.html

在 Windows 程序,可以使用 `CreateThread` 函数来创建一个新线程。如果需要让新线程线程同步,可以使用 Windows API 提供的同步机制,例如事件对象、互斥量、临界区等。 以下是一个示例代码,演示如何使用事件对象来实现线程等待新线程执行完毕: ```c++ #include <iostream> #include <Windows.h> DWORD WINAPI thread_func(LPVOID lpParam) { std::cout << "Thread started" << std::endl; // 线程执行的代码 std::cout << "Thread ended" << std::endl; SetEvent((HANDLE)lpParam); // 通知线程 return 0; } int main() { HANDLE hEvent = CreateEvent(NULL, FALSE, FALSE, NULL); // 创建事件对象 if (hEvent == NULL) { std::cerr << "Failed to create event object" << std::endl; return 1; } HANDLE hThread = CreateThread(NULL, 0, thread_func, hEvent, 0, NULL); // 创建线程 if (hThread == NULL) { std::cerr << "Failed to create thread" << std::endl; CloseHandle(hEvent); return 1; } WaitForSingleObject(hEvent, INFINITE); // 等待事件 std::cout << "Main thread ended" << std::endl; CloseHandle(hThread); CloseHandle(hEvent); return 0; } ``` 在这个示例,我们创建了一个事件对象 `hEvent`,并将它作为参数传递给新线程的 `thread_func()` 函数。在新线程执行完毕后,调用 `SetEvent()` 函数通知线程线程调用 `WaitForSingleObject()` 函数等待事件对象,直到新线程执行完毕并通知线程。最后,线程结束并释放资源。 需要注意的是,在使用事件对象等同步机制时,需要合理设置对象的初始状态和使用方式,否则可能会导致线程死锁或其他问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值