WaitForSingleObject死锁

时间:2015-11-05 17:32:13

标签: c++ multithreading winapi 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;
        }   
    }
}

我的OS / BSP USB驱动程序代码中设置了事件对象USB_PHY_CONNUSB_PHY_DISCONN,它将检测硬件USB连接并继续使用SetEvent()设置相应的事件对象

阅读WaitForSingleObject()的文档,它没有明确说明它必须在一个线程中使用,虽然在多次读取后我觉得它是隐含的,但我不是100%肯定。

我遇到的问题是代码第一次通过while循环运行(即,usb最初是断开连接,然后连接并断开连接),我的系统运行良好且不会挂起。但是,重新连接USB后,我的系统会冻结。我的设备无响应/用户界面冻结,代码丢失。

现在,当我杀死上面代码进入的过程时,一切都会重新启动并继续正常运行。我做了一些阅读,似乎WaitForSingleObject()冒着可能出现死锁的风险,但我也注意到它总是以线程的形式出现。

我的问题是WaitForSingleObject()是否必须在线程中使用?如果我在main中的无限循环中使用它,这是否会导致死锁/系统冻结的高风险?

注意:这是一个平台构建器Windows嵌入式CE 7项目与VS2008。

1 个答案:

答案 0 :(得分:1)

您无法在外部执行代码!有一个“主”线程从main开始,但这也是一个与其他线程一样的线程。

也就是说,死锁需要2个线程和2个同步点。一个线程锁定A,另一个线程锁定B,然后两个线程在尝试获取另一个锁时阻塞。

这可以通过锁定命令绝对解决。如果锁A在之前始终锁定,那么在具有A和其他具有锁B的线程的线程之间不会发生死锁。

更理论化的方法证明问题是锁定图中的一个循环。循环A = B是长度为2的最简单循环.A-> B-> C-> A也可以是死锁。锁定顺序的有向非循环图对应于无死锁程序。