Windows Win32 其余线程同步(按游戏多线程脚本场景排序)
分两大类:内核对象(有HANDLE,可配合WaitForSingleObject)、用户态轻量锁(无句柄,速度更快,仅限本进程)
一、内核同步对象(和CreateEvent同类型,内核对象,返回HANDLE)
1. CreateMutex 互斥量(Mutex)
HANDLE CreateMutex(LPSECURITY_ATTRIBUTES, BOOL bInitialOwner, LPCTSTR lpName);
// 配套:WaitForSingleObject、ReleaseMutex、CloseHandle
- 作用:独占互斥,同一时刻只允许一个线程拿到锁,保护共享变量/共享资源。
- 特点: ✅ 支持命名,跨进程同步; ✅ 遗弃检测:线程没ReleaseMutex直接退出,其他等待线程能检测到; ✅ 可递归(同一个线程可以多次Wait获取); ❌ 内核态,比临界区慢。
- 适合:多账号线程保护全局共享数据,不同进程之间互斥。
区别Event:Event是通知;Mutex是排他锁,用来保护资源,不是发信号。
2. CreateSemaphore 信号量(Semaphore)
HANDLE CreateSemaphore(LPSECURITY_ATTRIBUTES, LONG lInitialCount, LONG lMaximumCount, LPCTSTR lpName);
// 配套:WaitForSingleObject、ReleaseSemaphore、CloseHandle
- 作用:资源池计数,控制最多N个线程同时进入。
- 原理:有计数器,Wait成功计数器-1;ReleaseSemaphore计数器+1。
- 例子:最多5个账号同时访问数据库,其余排队。
- 支持命名,跨进程。
二、用户态轻量同步(无HANDLE,同进程,性能高,游戏脚本首选)
3. CriticalSection 临界区
// 初始化
InitializeCriticalSection(CRITICAL_SECTION* cs);
// 进入(加锁)
EnterCriticalSection(cs);
TryEnterCriticalSection(cs); // 非阻塞尝试加锁
// 离开(解锁)
LeaveCriticalSection(cs);
// 销毁
DeleteCriticalSection(cs);
- 只在同一个进程内使用,不能跨进程。
- 底层:先自旋,自旋失败才进入内核阻塞,性能远高于Mutex。
- 支持递归加锁;
- 适合:游戏多线程保护共享内存、全局变量(你多账号脚本最常用)。
缺点:没有超时等待,EnterCriticalSection一旦拿不到锁会无限阻塞。
4. SRWLock 精简读写锁(Slim Reader/Writer Lock)
InitializeSRWLock(PSRWLOCK SRWLock);
// 读锁(共享,多个读线程可同时进入)
AcquireSRWLockShared
ReleaseSRWLockShared
// 写锁(独占,只能一个写线程)
AcquireSRWLockExclusive
ReleaseSRWLockExclusive
- 现代Windows推荐,读多写少场景性能极强。
- 不支持递归锁;同进程,用户态。
- 适用:大量线程读共享配置,偶尔修改。
5. Interlocked 原子操作系列(InterlockedIncrement / InterlockedCompareExchange 等)
不属于锁,CPU硬件原子指令,完全无内核切换,速度最快
- 函数:
InterlockedIncrement、InterlockedDecrement、InterlockedCompareExchange(CAS) - 用途:简单的计数器、标记位、状态flag,不需要保护一大段代码,只对单个变量原子读写。
多账号计数、全局开关标记,优先用这个,开销最小。
三、等待函数
这些是等待 API,不是创建对象函数,但所有内核同步对象都靠它们等待:
WaitForSingleObject:等待单个内核对象(Event/Mutex/Semaphore/ 线程句柄)WaitForMultipleObjects:同时等待多个句柄数组,可等任意一个 / 全部WaitForSingleObjectEx / WaitForMultipleObjectsEx:可警报等待,支持 IO 异步回调SignalObjectAndWait:原子操作:置位 A 对象信号,同时等待 B 对象,防止竞态
四、简单选型对照表(适配你的游戏多账号场景)
表格
| 原语 | 核心用途 | 跨进程 | 性能 |
|---|---|---|---|
| CreateEvent | 事件通知(唤醒一组 / 单个线程) | ✅ | 中等 |
| CreateMutex | 全局互斥锁,跨进程保护资源 | ✅ | 较慢 |
| CreateSemaphore | 控制并发数量,资源池限流 | ✅ | 中等 |
| CriticalSection | 单进程互斥保护共享内存 | ❌ | 快 |
| SRWLock | 读多写少场景 | ❌ | 很快 |
| Interlocked | 单个变量原子计数 / 标记 | ❌ | 极快 |
五、游戏脚本开发的选型建议
- 通知线程启动 / 暂停 →
CreateEvent(手动重置一次性唤醒全部账号线程) - 保护共享全局变量(账号状态、任务队列) →
CriticalSection - 简单全局计数器、开关标记 →
InterlockedCompareExchange - 限制并发数量,最多 N 个账号同时执行 IO →
Semaphore - 多个游戏进程之间互斥 →
Mutex
六、容易踩坑区分
- Event:发通知,不保护数据;
- Mutex / CriticalSection:保护数据独占访问;
- Semaphore:控制并发数量;
- Interlocked:单个变量原子操作。