You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

多实例场景下Mutex行为异常问题及原理咨询

问题分析与解答

核心问题:已持有Mutex时调用WaitForSingleObject的行为

Windows平台下的Mutex是可重入(递归)锁:

  • 同一个线程如果已经持有该Mutex,再次调用WaitForSingleObject(Mutex, INFINITE)会直接返回成功,同时Mutex的内部引用计数加1。
  • 每次调用ReleaseMutex会将引用计数减1,只有当引用计数降至0时,Mutex才会被真正释放,其他等待的线程才有机会获取它。

你的代码问题根源

当bInitialOwner设为true时:

  1. 第一个实例创建Mutex后,直接持有该锁(引用计数=1)。
  2. 进入else分支的死循环,第一次调用WaitForSingleObject:因为线程已持有锁,直接成功,引用计数变为2。
  3. 调用ReleaseMutex后,引用计数回到1——此时Mutex并未真正释放,因为引用计数没到0。
  4. 循环重复上述操作:每次Wait让计数+1,Release让计数-1,始终维持在1的状态。Mutex永远不会被真正释放,导致第二个实例的WaitForSingleObject永远处于等待状态。

而当bInitialOwner设为false时,第一个实例创建Mutex后不持有锁,第一次WaitForSingleObject会真正获取锁(计数=1),Release后计数归0,Mutex被释放,第二个实例就能正常获取。

修正建议

方案1:修正第一个实例的初始锁状态

在进入循环前,先释放一次Mutex,将初始的引用计数降到0:

else {
    // 因为创建时bInitialOwner=true,先释放一次让Mutex处于可用状态
    ReleaseMutex(Mutex);
    while (1) {
        WaitForSingleObject(Mutex, INFINITE); 
        std::cout << TEXT("Input data into shared memory: "); 
        std::cin.getline(charw, 255);
        ReleaseMutex(Mutex);

        WaitForSingleObject(Mutex, INFINITE);
        std::cout << "Content in memory: " << charw << std::endl;
        ReleaseMutex(Mutex);
    }
}

方案2:直接设置bInitialOwner为false(推荐)

这是更符合Mutex常规用法的方式:创建时不持有锁,需要同步时再主动获取:

// Create mutex
HANDLE Mutex = CreateMutexW(nullptr, false, L"share");

额外优化

代码中创建的Semaphore完全没有被使用,建议移除相关代码,避免不必要的系统资源占用。

内容的提问来源于stack exchange,提问作者game mone

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 00:30:08