多实例场景下Mutex行为异常问题及原理咨询
问题分析与解答
核心问题:已持有Mutex时调用WaitForSingleObject的行为
Windows平台下的Mutex是可重入(递归)锁:
- 同一个线程如果已经持有该Mutex,再次调用
WaitForSingleObject(Mutex, INFINITE)会直接返回成功,同时Mutex的内部引用计数加1。 - 每次调用
ReleaseMutex会将引用计数减1,只有当引用计数降至0时,Mutex才会被真正释放,其他等待的线程才有机会获取它。
你的代码问题根源
当bInitialOwner设为true时:
- 第一个实例创建Mutex后,直接持有该锁(引用计数=1)。
- 进入
else分支的死循环,第一次调用WaitForSingleObject:因为线程已持有锁,直接成功,引用计数变为2。 - 调用
ReleaseMutex后,引用计数回到1——此时Mutex并未真正释放,因为引用计数没到0。 - 循环重复上述操作:每次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
相关产品推荐
相关产品推荐

