首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Mutex API :Mutex挂起,尽管它已经发布

Mutex API :Mutex挂起,尽管它已经发布
EN

Stack Overflow用户
提问于 2016-11-27 16:01:29
回答 1查看 495关注 0票数 0

我正在尝试通过互斥建立进程间的通信。我有一个过程这样做:

代码语言:javascript
复制
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);

第二个程序(不同的过程)这样做:

代码语言:javascript
复制
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 ms;即使我将它设置为更高的值,我也会得到相同的结果),以便通过WaitForSingleObject函数声明互斥锁的所有权。我遗漏了什么?在过去的几个小时里我一直在打我自己的脑袋。

提前谢谢。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-11-27 17:44:05

代码语言:javascript
复制
  HANDLE hMutex = CreateMutex(NULL, TRUE, "amutex_name");

真正的论点并不如你所希望的那样。互斥对象是可重入的,允许线程多次获取它.它内部计算所有者线程输入的次数,释放互斥体需要同等数量的ReleaseMutex()调用。

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

更糟糕的是,在CloseHandle()调用之后,操作系统现在将互斥标记为放弃。如果状态不好,它知道原始线程永远无法将内部计数器返回到0。这使得第二个程序中的WFSO调用在WAIT_ABANDONED中永久失败。你大概没等20分钟才能进入那种状态。

通过错误的传球来取得领先。通过改进错误处理,如果您没有从WFSO调用中获得WAIT_OBJECT_0,那么就发生了一些非常糟糕的事情,您唯一的办法就是终止程序。

票数 9
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/40830886

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档