【问题标题】:Windows mutex WAIT_OBJECT_0 and WAIT_ABANDONEDWindows 互斥体 WAIT_OBJECT_0 和 WAIT_ABANDONED
【发布时间】:2014-09-17 22:50:16
【问题描述】:

我不明白多线程程序中做的有什么区别:

WaitForSingleObject(hMutex, INFINITE);
// Critical secontion here
ReleaseMutex(hMutex);

做一些更复杂的事情,比如MSDN example

dwWaitResult = WaitForSingleObject( 
            ghMutex,    // handle to mutex
            INFINITE);  // no time-out interval

switch (dwWaitResult) 
{
    // The thread got ownership of the mutex
    case WAIT_OBJECT_0: 
        __try { 
            // TODO: Write to the database
            printf("Thread %d writing to database...\n", 
                GetCurrentThreadId());
            dwCount++;
        } 
        __finally { 
            // Release ownership of the mutex object
            if (! ReleaseMutex(ghMutex)) 
            { 
                // Handle error.
            } 
        } 
        break; 

    // The thread got ownership of an abandoned mutex
    // The database is in an indeterminate state
    case WAIT_ABANDONED: 
        return FALSE; 
}

【问题讨论】:

  • 第一个例子假设WaitForSingleObject成功,第二个例子考虑到它可能会失败。
  • @JonathanPotter 在将互斥体句柄传递给它时,WaitForSingleObject 何时会失败?
  • MSDN 没有比 FALSE 更大的武器,他们所能做的就是大写。 WAIT_ABANDONED 是适当的大写,它是您的代码中的一个讨厌的错误,您总是想知道。制造很多很多的噪音。不要犹豫 RaiseException。就像 dbase 提供者所做的那样。
  • @HansPassant 不确定我是否理解你的意思。
  • 我必须努力解决更大的问题,David 的帖子是对此做一些事情的灵感。我什么时候找时间。

标签: c multithreading winapi mutex


【解决方案1】:

快速回答,但第一个示例假定WaitForSingleObject 成功,而第二个示例处理(部分)错误。更重要的是,在第二个示例中,只有在安全获取互斥体时,代码才会对受保护的数据进行操作,这意味着数据(理论上)处于已知状态。

WaitForSingleObject 可能在此处返回两个可能的错误:WAIT_ABANDONEDWAIT_FAILED

  • WAIT_FAILED 可能会发生,例如,如果您的 Mutex 已关闭,在这种情况下,您的软件可能会出错。在这种情况下,您可以记录它发生的事实并尝试尽可能干净地退出。

  • WAIT_ABANDONED 表示持有 Mutex 的线程已退出或被杀死。无论哪种方式,您的程序都处于未知状态,受保护的数据处于未知状态,您应该尽可能干净地退出......只是不要触摸数据,因为您不能安全地这样做。

请记住,WAIT_ABANDONED 可能是由于某人在调试器(或类似 Process Explorer)中打开您的进程并杀死了一个线程,而不仅仅是您自己的程序错误...所以您需要处理它。我想同样的情况也可能导致WAIT_FAILED...所以也处理一下。

【讨论】:

  • 如果它是一个我不希望人们调试的程序怎么办?最好不要检查这些错误?
  • @Omlis532:您应该经常检查这些错误。我以调试器为例...我可以使用 Process Explorer 在您的进程中终止一个线程。如果我这样做了,那么是的,如果我最终得到损坏的数据是我的错,但是如果您的程序检测到发生了类似的事情,并尝试优雅地死去。放弃互斥锁的原因可能有很多,如果你得到它,你将不知道你的受保护数据处于什么状态。
猜你喜欢
  • 1970-01-01
  • 2011-10-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-02-11
  • 2013-06-08
相关资源
最近更新 更多