Win32 API : Mutex 挂起,即使它已被释放

Win32 API : Mutex hangs even though it's released

我正在尝试通过互斥设置进程间通信。我有一个流程可以执行此操作:

HANDLE hMutex = CreateMutex(NULL, TRUE, "amutex_name");
if (!hMutex) {
    puts("Error creating mutex. Aborting.");
    return;
}
for (int i = 0; i < 500; ++i) {
    if (WaitForSingleObject(hMutex, INFINITE) == WAIT_FAILED) {
        puts("Error waiting for mutex. Aborting.");
        return;
    }
    if (!ReleaseMutex(hMutex)) {
        puts("Error releasing mutex. Aborting.");
        return;
    }
    puts("MUTEX RELEASED");
    Sleep(2000);
}
CloseHandle(hMutex);

第二个程序(不同的进程)执行此操作:

HANDLE hMutex = CreateMutex(NULL, FALSE, "amutex_name");
if (!hMutex) {
    puts("Error creating mutex. Aborting.");
    return;
}
while (1) {
    if (WaitForSingleObject(hMutex, INFINITE) == WAIT_FAILED)
        continue;
    if (!ReleaseMutex(hMutex)) {
        puts("Error releasing mutex. Aborting.");
        return;
    }
    puts("GOT ONE");
}
CloseHandle(hMutex);

第一个程序按预期输出了很多MUTEX RELEASED,但第二个程序没有输出任何内容。这是为什么?...从第一个程序释放互斥锁后,第二个程序应该有足够的时间(2000 毫秒;即使我将其设置得更高,我也会得到相同的结果)通过 WaitForSingleObject 函数。我错过了什么?在过去的几个小时里,我一直在敲自己的脑袋。

提前致谢。

  HANDLE hMutex = CreateMutex(NULL, TRUE, "amutex_name");

TRUE 参数没有达到您希望的效果。一个互斥量是可重入,一个线程被允许多次获取它。它在内部计算所有者线程进入它的次数,释放互斥量需要相同次数的 ReleaseMutex() 调用。

因此第一个程序使用 bInitialOwner = TRUE 参数立即获取它。然后 WFSO 调用再次获取它 ,内部计数器将为 2。ReleaseMutex 调用只能将计数器降低回 1,不足以释放它。因此,只要循环为 运行.

,第二个程序就永远无法获取它

CloseHandle() 调用后情况变得更糟,OS 现在将互斥锁标记为 已放弃。一个糟糕的状态,它知道原始线程永远无法将内部计数器恢复为 0。这使得第二个程序中的 WFSO 调用永久失败并返回 WAIT_ABANDONED。您可能没有等到大约 20 分钟就进入了那种状态。

通过 FALSE 获得领先。并且通过改进错误处理,如果您没有从 WFSO 调用中得到 WAIT_OBJECT_0 返回,那么就会发生非常糟糕的事情,您唯一的办法就是终止程序。