C++多线程编程:同步之互斥量Mutex
2023-09-27 14:20:25 时间
目录
C++使用内核对象互斥体(Mutex)来实现线程同步锁。当两个或更多线程需要同时访问一个共享资源时,Mutex可以只向一个线程授予对共享资源的独占访问权。如果一个线程获取了互斥体,则要获取该互斥体的第二个线程将被挂起,直到第一个线程释放该互斥体。
1. CreateMutex()
https://docs.microsoft.com/en-us/windows/win32/api/synchapi/nf-synchapi-createmutexa
HANDLE CreateMutexA(
LPSECURITY_ATTRIBUTES lpMutexAttributes,
BOOL bInitialOwner,
LPCSTR lpName
);
2. ReleaseMutex()
https://docs.microsoft.com/en-us/windows/win32/api/synchapi/nf-synchapi-releasemutex
BOOL ReleaseMutex(
HANDLE hMutex
);
3. WaitForSingleobject()
https://docs.microsoft.com/en-us/windows/win32/api/synchapi/nf-synchapi-waitforsingleobject
DWORD WaitForSingleObject(
HANDLE hHandle,
DWORD dwMilliseconds
);
该函数需要传递一个内核对象句柄,如果该内核对象处于未通知状态,则该函数导致线程进入阻塞状态;如果该内核对象处于已通知状态,则该函数立即返回 WAIT_OBJECT()第二个参数指明要等待的时间(毫秒),INFINITE表示无限等待,如果第二个参数为0,那么函数立即返回。如果等待超时,该函数返 WAIT_TIMEOUT如果该函数失败,返回 WAIT_FAILED。
该函数需要传递一个内核对象句柄,如果该内核对象处于未通知状态,则该函数导致线程进入阻塞状态;如果该內核对象处于已通知状态,则该函数立即返回 WAIT_OBJECT()。第二个数指明要等待的时间(毫秒),INFINITE表示无限等待,如果第二个参数为0,那么函数立即返回。如果等待超时,该函数返 WAIT_TIMEOUT。
如果该函数失败,返回 WAIT_FAILED
4. CloseHandle()
https://docs.microsoft.com/en-us/windows/win32/api/handleapi/nf-handleapi-closehandle
BOOL CloseHandle(
HANDLE hObject
);
5. 示例代码
#include<process.h>
#include<windows.h>
#include<stdio.h>
void __cdecl SellThread1(void* param);
void __cdecl SellThread2(void* param);
//100张票
int tickets = 100;
HANDLE hMutex = INVALID_HANDLE_VALUE;
int main()
{
//创建互斥体,此刻为有信号状态
hMutex = CreateMutex(NULL, FALSE, L"售票互斥体");
printf("开始卖票了!\n");
//创建两个售票窗口
uintptr_t t1 = _beginthread(SellThread1, 0, "售口窗口A");
uintptr_t t2 = _beginthread(SellThread2, 0, "售口窗口B");
//无限等待两个线程全部执行完毕
HANDLE hArr[] = { (HANDLE)t1, (HANDLE)t2 };
WaitForMultipleObjects(2, hArr, true, INFINITE);
printf("卖票结束!\n");
return 0;
}
void __cdecl SellThread1(void* param)
{
char *name = (char *)param;
while (tickets>0)
{
//如果这个互斥体为有信号状态(没有线程拥有它),则线程获取它后继续执行
WaitForSingleObject(hMutex, INFINITE);
if (tickets > 0)
{
Sleep(10);
//CPU恰好执行到这里,这个时候线程时间片到了,并且此时还剩最后一张票
printf("%s卖出第%d张票!\n", name, tickets--);
}
//释放对互斥体的拥有权,它变成有信号状态
ReleaseMutex(hMutex);
}
}
void __cdecl SellThread2(void* param)
{
char *name = (char *)param;
while (tickets > 0)
{
//如果这个互斥体为有信号状态(没有线程拥有它),则线程获取它后继续执行
WaitForSingleObject(hMutex, INFINITE);
if (tickets > 0)
{
Sleep(10);
//CPU恰好执行到这里,这个时候线程时间片到了,并且此时还剩最后一张票
printf("%s卖出第%d张票!\n", name, tickets--);
}
//释放对互斥体的拥有权,它变成有信号状态
ReleaseMutex(hMutex);
}
}
6. Mutex实现一个程序只允许允许一个实例(进程)
#include<process.h>
#include<windows.h>
#include<stdio.h>
int main()
{
//创建互斥体实现一个程序只允许允许一个实例(进程)
HANDLE hMutex = CreateMutex(NULL, FALSE, L"售票互斥体");
if (GetLastError() == ERROR_ALREADY_EXISTS)
{
printf("程序已经运行了,退出!\n");
getchar();
CloseHandle(hMutex);
return 0;
}
printf("第一次运行程序!\n");
getchar();
return 0;
}
相关文章
- Linux多线程实践(10) --使用 C++11 编写 Linux 多线程程序
- 【C++游戏引擎Easy2D】Random随机数,不同于Rand,做游戏必备
- 最全面的C/C++编码规范总结
- c/c++多线程模拟系统资源分配(并通过银行家算法避免死锁产生)
- Windows下使用Dev-C++开发基于pthread.h的多线程程序
- 【C/C++开发】多线程编程中的join函数
- C++常用算法(五):生成【accumulate:计算容器元素累计总和】【fill:向容器中添加元素】
- [c++] Class
- 应用程序启动后修改自身EXE文件或自删除EXE文件(附VC++6.0源码)
- c++多线程编程(二)
- C++类与内存
- C++ 找标定圆点
- C/C++ 数据结构之算法
- 从Java到C++——union的使用方法
- C++ - 使用Websocket++编写客户端连接WebSocket服务器并进行通信
- C++多线程同步之Mutex(互斥量)
- C++11多线程编程-两个进程轮流打印1~100
- c++中nlohmann json的基本使用教程
- C++11多线程教学(一)
- c++多线程编程之互斥对象(锁)的使用之----死锁
- C++ | 多线程编程(二) 互斥器Mutex
- vc++之stdafx.h
- 临时起异,要进入C++领域耍一个程序
- 【C++11 多线程】future与promise(八)
- 【C++11 多线程】原子操作(六)
- 【C++11 多线程】竞争条件与互斥锁mutex(四)
- [C++ STL] 常用算法总结
- 站在巨人的肩膀上,C++开源库大全