Windows多线程CreateMutex同步异常:g_Count未达线程总数问题
问题分析与修复
问题根源
你的代码存在两个核心问题,导致全局变量g_Count最终值始终小于线程总数THREAD_NUM:
非法字符串格式导致线程崩溃
线程函数中的printf语句使用了直接换行(而非C语言标准的转义字符\n):printf("Thread %d plus 1 to g_Count. ", GetCurrentThreadId());这种写法属于语法错误,线程执行到该语句时会直接崩溃终止——既无法完成
g_Count++操作,也不会释放互斥锁。后续线程调用WaitForSingleObject会返回WAIT_ABANDONED(表示互斥锁被前序线程遗弃),从而跳过g_Count++的逻辑。循环变量地址共享的潜在风险
创建线程时传递的是循环变量i的地址&i,所有线程共享同一个内存地址。虽然当前线程函数没有使用该参数,但如果后续需要基于该参数做逻辑处理,会因为主线程循环中i的快速变化,导致线程读取到错误的数值(比如所有线程都读取到最终的THREAD_NUM)。
修复后的完整代码
#include <windows.h> #include <stdio.h> const unsigned int THREAD_NUM = 100; unsigned int g_Count = 0; HANDLE g_Mutex; DWORD WINAPI ThreadFunc(LPVOID); int main() { HANDLE hThread[THREAD_NUM]; g_Mutex = CreateMutex(NULL, FALSE, NULL); // 为每个线程分配独立变量存储序号,避免地址共享问题 unsigned int threadSeq[THREAD_NUM]; for (unsigned int i = 0; i < THREAD_NUM; i++) { threadSeq[i] = i; hThread[i] = CreateThread(NULL, 0, ThreadFunc, &threadSeq[i], 0, NULL); } WaitForMultipleObjects(THREAD_NUM, hThread, TRUE, INFINITE); for(unsigned int i = 0; i < THREAD_NUM; i++ ) CloseHandle(hThread[i]); CloseHandle(g_Mutex); printf("最终g_Count的值为:%u\n", g_Count); return 0; } DWORD WINAPI ThreadFunc(LPVOID p) { DWORD result = WaitForSingleObject(g_Mutex, INFINITE); if (result == WAIT_OBJECT_0) { g_Count++; // 使用标准转义字符\n换行,避免线程崩溃 printf("线程%u(ID:%d)将g_Count自增1,当前值:%u\n", *(unsigned int*)p, GetCurrentThreadId(), g_Count); ReleaseMutex(g_Mutex); } // 增加异常情况处理,便于排查问题 else if (result == WAIT_ABANDONED) { printf("线程%d检测到互斥锁被遗弃\n", GetCurrentThreadId()); } return 0; }
修复说明
- 修正
printf语句的字符串格式,使用\n作为换行符,彻底解决线程崩溃问题。 - 为每个线程创建独立的序号变量,传递该变量的地址给线程函数,消除循环变量地址共享的风险。
- 增加对
WAIT_ABANDONED返回值的处理,便于排查互斥锁相关的异常情况。
内容的提问来源于stack exchange,提问作者unitpi
相关产品推荐
相关产品推荐

