win32相关(互斥体)
互斥体
内核级临界资源怎么处理?
有两个不同进程中的线程,访问内核中的临界资源,该怎么实现线程安全
互斥体其实就是一个内核级的跨进程访问令牌,与在同一个进程中的临界区不同的是,同一个进程中的不同线程,可以使用临界区来拿到令牌进行获取资源,但在不同进程中,想要访问相同资源时,就需要在内核也有一个访问令牌,这个就是互斥体
创建一个互斥体
#include<iostream>
#include<windows.h>/*CreateMutexW(LPSECURITY_ATTRIBUTES lpMutexAttributes, // 安全描述符BOOL bInitialOwner, // 如果为 TRUE,则创建的互斥锁的初始拥有者为当前进程;如果为 FALSE,则创建的互斥锁的初始拥有者为空LPCWSTR lpName // 互斥锁的名称
);*/int main() {// 创建互斥锁(互斥体)HANDLE hMyMutex = CreateMutex(NULL, FALSE, L"MyMutex");// 获取互斥锁WaitForSingleObject(hMyMutex, INFINITE);while (true) { // 代码Sleep(1000);std::cout << "I am working..." << std::endl;}// 释放互斥锁ReleaseMutex(hMyMutex);return 0;
}
当这个程序运行起来两个时,只会有一个程序打印 I am working… ,另一个进入阻塞状态直到获取互斥体的进程释放获取的互斥体令牌
互斥体与线程锁的区别
- 线程锁只能用于单个进程间的线控制
- 互斥体可以设定等待超时,但线程锁不能
- 线程意外终结时,互斥体可以避免无限等待
- 互斥体效率没有线程锁高
tips:大多数游戏或程序限制多开的原理其实就是使用了互斥体
#include<iostream>
#include<windows.h>/*CreateMutexW(LPSECURITY_ATTRIBUTES lpMutexAttributes, // 安全描述符BOOL bInitialOwner, // 如果为 TRUE,则创建的互斥锁的初始拥有者为当前进程;如果为 FALSE,则创建的互斥锁的初始拥有者为空LPCWSTR lpName // 互斥锁的名称
);*/int main() {// 创建互斥锁(互斥体)HANDLE hMyMutex = CreateMutex(NULL, FALSE, L"MyMutex");// 如果已经创建了名为"MyMutex的程序",再创建相同名称的互斥体时,GetLastError()会返回ERROR_ALREADY_EXISTSif (GetLastError() == ERROR_ALREADY_EXISTS) {MessageBox(NULL, L"当前程序已经运行,请退出", L"Error", MB_OK | MB_ICONERROR);ExitProcess(0);}// 获取互斥锁WaitForSingleObject(hMyMutex, INFINITE);while (true) { // 代码Sleep(1000);std::cout << "I am working..." << std::endl;}// 释放互斥锁ReleaseMutex(hMyMutex);return 0;
}