互斥锁的使用(CreateMutex等使用)
目录
- 1.CreateMutex函数原型
- 2.WaitForSingleObject的理解
- 3.CreateMutex和WaitForSingleObject的配合使用
- 3.1如何加锁
- 3.2如何解锁
- 4.使用示例
- 5.注意
1.CreateMutex函数原型
HANDLE CreateMutex(LPSECURITY_ATTRIBUTES lpMutexAttributes, // 指向安全属性的指针BOOL bInitialOwner, // 初始化互斥对象的所有者,如果希望进程立即拥有互斥体则设为FALSELPCTSTR lpName // 指向互斥对象名的指针
);
功能:创建一个互斥体(MUTEX)
- CreateMutex只是创建了一把锁, 这把锁你用来锁门还是锁抽屉还是锁你对象的内裤都由你自己决定。
- lpName是指定这把锁的名字. 你要不给这把锁取个名字都可以. 只是有了相同的名字, 在跨进程加锁的时候, 就可以得到同一把锁。
- HANDLE m_hMutex = CreateMutex(NULL,TRUE,“cplusplus_me”); 只是创建了一把锁, 到目前这句完成, 他没有锁任何东西。
如果函数成功执行,将返回一个互斥量对象的句柄。如果在CreateMutex()执行前已经存在有相同名字的互斥量,函数将返回这个已经存在互斥量的句柄,并且可以通过GetLastError()得到错误代码ERROR_ALREADY_EXIST
。可见,通过对错误代码ERROR_ALREADY_EXIST
的检测可以实现CreateMutex()对进程的互斥。
通过这个性质,就可以做一个避免进程重复打开的功能。
部分代码如下:
HANDLE m_hMutex = CreateMutex(NULL, FALSE, "Sample07");// 创建互斥量
if (GetLastError() == ERROR_ALREADY_EXISTS){// 如果已有互斥量存在则释放句柄并复位互斥量 CloseHandle(m_hMutex);m_hMutex = NULL;// 程序退出return FALSE;};
2.WaitForSingleObject的理解
请看:关于WaitForSingleObject的理解
3.CreateMutex和WaitForSingleObject的配合使用
3.1如何加锁
一般使用WaitForSingleObject(hMutex, INFINITE);
加锁
3.2如何解锁
一般使用ReleaseMutex(hMutex);
解锁
这里写被加锁的东西. 一般是操作一些共享数据(占用系统内存)。
4.使用示例
问题:
假设 一个剧团卖票 一共10章票,3个电脑在卖它,每个人选座位买票大约花费500ms。模拟这样的场景,输出顺序是按购买顺序。
HANDLE hMutex = NULL;
//共享资源
static int num = 0; //目前一张都没卖出去#define NUMSIZE 10 //num最大是10 可以更改//子线程函数
unsigned long __stdcall ChildThreadFunc1(LPVOID pM)
{while(num<NUMSIZE)
{Sleep(500); //花500ms选取位置支付等过程//加锁WaitForSingleObject(hMutex, INFINITE);//等待互斥量 if(num<NUMSIZE){ num++;printf("ThreadFunc1 num:%d\n", num);}//解锁ReleaseMutex(hMutex); //执行完放弃对数据的所有权
}
return 0;}
//子线程函数
unsigned long __stdcall ChildThreadFunc2(LPVOID pM)
{while (num < NUMSIZE)
{Sleep(500);
//加锁
WaitForSingleObject(hMutex, INFINITE);//等待互斥量
if (num<NUMSIZE)
{num++;
printf(“ThreadFunc2 num:%d\n”, num);
}
//解锁
ReleaseMutex(hMutex); //执行完放弃对数据的所有权
}
return 0;
}
//子线程函数
unsigned long __stdcall ChildThreadFunc3(LPVOID pM)
{while (num <NUMSIZE)
{//加锁
Sleep(500);
WaitForSingleObject(hMutex, INFINITE);//等待互斥量
if (num<NUMSIZE)
{num++;
printf(“ThreadFunc3 num:%d\n”, num);
}
//解锁
ReleaseMutex(hMutex); //执行完放弃对数据的所有权
}
return 0;
}int main()
{hMutex = CreateMutex(NULL,/*指向安全属性的指针*/FALSE,/*初始化互斥对象的所有者 如果希望进程立即拥有互斥体则设为FALSE*/ NULL);/*指向互斥对象名的指针*/
HANDLE handle[3] = { 0 };
handle[0] = CreateThread(NULL, 0, ChildThreadFunc1, NULL, 0, NULL);
handle[1] = CreateThread(NULL, 0, ChildThreadFunc2, NULL, 0, NULL);
handle[2] = CreateThread(NULL, 0, ChildThreadFunc3, NULL, 0, NULL);//阻塞等待
Sleep(8000);printf("主线程 num:%d\n", num);
for (int i = 0; i < 3; i++)
{CloseHandle(handle[i]);
}
CloseHandle(hMutex);
system("pause");
return 0;}
运行结果:
5.注意
有如下代码:
运行结果是不是有点吃惊,其实你停下来仔细想想也就通了,每个进程本来就有一个主线程。因为你创建的mutex一开始没有拥有者,所以第一次WaitForSingleObject
会使当前线程获得mutex的所有权,并立即返回
mutex的所有线程再次等待mutex时也不会阻塞,因此第二次WaitForSingleObject
也会马上返回,因为你是在同一个线程中调用WaitForSingleObject的。
互斥锁的使用(CreateMutex等使用)相关推荐
- Linux多线程编程---线程间同步(互斥锁、条件变量、信号量和读写锁)
本篇博文转自http://zhangxiaoya.github.io/2015/05/15/multi-thread-of-c-program-language-on-linux/ Linux下提供了 ...
- windows线程 互斥锁CreateMutex、ReleaseMutex、CloseHandle
互斥 相关问题 多线程下代码或资源的共享使用. 互斥的使用 1.创建互斥 HANDLE CreateMutex( LPSECURITY_ATTRIBUTES lpMutexAttributes,//安 ...
- C 多线程的互斥锁应用RAII机制
什么是RAII机制 RAII是Resource Acquisition Is Initialization(翻译成 "资源获取即初始化")的简称,是C 语言的一种管理资源.避免资源 ...
- java 信号量 互斥锁_线程同步(互斥锁与信号量的作用与区别)
"信号量用在多线程多任务同步的,一个线程完成了某一个动作就通过信号量告诉别的线程,别的线程再进行某些动作(大家都在semtake的时候,就阻塞在 哪里).而互斥锁是用在多线程多任务互斥的,一 ...
- C语言mutex使用案例,C语言 如何使用互斥锁严格交替使用两个线程?
我需要创建两个严格交替的线程.这是我使用的示例代码: #include #include using std::cout; using std::endl; HANDLE g_hMutex1; HAN ...
- 互斥锁、临界区和事件
文章目录 一.互斥锁的介绍 二.临界区介绍 三.关于条件的使用 一.互斥锁的介绍 互斥锁用于控制多个线程对他们之间共享资源互斥访问的一个信号量.也就是说是为了避免多个线程在某一时刻同时操作一个共享资源 ...
- C++多线程 互斥锁 信号量 事件 临界区
一.互斥锁 1.先熟悉熟悉API 1,创建互斥锁,并反正一个句柄 HANDLE CreateMutex( LPSECURITY_ATTRIBUTESlpMutexAttributes, // 指向安全 ...
- Windwos下的互斥锁,事件以及事件的手动重置和自动重置的区别
事件的自动重置:两个线层同时访问一个函数,该函数会对全局变量进行操作,用事件进行互斥,假设这个事件初始化有信号 在经过WAITFORSIGALOBJECT()后事件就会变为没有信号,另外一个线程无 ...
- Python 多线程总结(2)— 线程锁、线程池、线程数量、互斥锁、死锁、线程同步
主要介绍使用 threading 模块创建线程的 3 种方式,分别为: 创建 Thread 实例函数 创建 Thread 实例可调用的类对象 使用 Thread 派生子类的方式 多线程是提高效率的一种 ...
- java锁(公平锁和非公平锁、可重入锁(又名递归锁)、自旋锁、独占锁(写)/共享锁(读)/互斥锁、读写锁)
前言 本文对Java的一些锁的概念和实现做个整理,涉及:公平锁和非公平锁.可重入锁(又名递归锁).自旋锁.独占锁(写)/共享锁(读)/互斥锁.读写锁 公平锁和非公平锁 概念 公平锁是指多个线程按照申请 ...
最新文章
- [转] 使用模板自定义 WPF 控件
- json工具类ObjectMapper的详细使用记录
- 快速开发平台网格部件合并单元格。
- android:descendantFocusability用法简析
- python extended,python list中的append 与 extended 的区别
- Android基础类之BaseAdapter
- 读《突然就走到了西藏》 | 保持呼吸,继续向前
- SLAM_BA中重投影误差e 关于相机位姿扰动量δξ 的雅克比矩阵J 公式推导
- OSI七层参考模型与5G协议
- 基于php考试系统设计与实现研究文毕业设计(论文)学生中期检查,毕业设计(论文)中期检查报告(学生填写)...
- 此ca根目录证书不受信任
- Winform中datagridview显示数据时,不显示特殊符号,如下划线不显示问题
- 5G通信在应急系统中的应用
- 推荐一波 Linux 网络工具
- 《乐跑宝典》读书笔记
- css html模板下载插件
- 微信小程序-编写图标的方法
- 在托马斯·哈代的五月中学习机器学习之新闻分类
- tar打包绝对路径文件
- 在Win7下通过SecureCRT 远程配置DynamipsGUI中的路由器--转载
热门文章
- ES(Elasticsearch)7.6.1安装教程
- zookeeper基本架构
- Mybatis 手动清除缓存
- Redis利用方式总结(Linux/Windows)
- win10安装sql2000 无法定位序数1于动态链接库c:\windows\system32\sqlunirl.dll
- Dell Latitude E7280 Compal CAZ10 LA-E122P Rev 1.0戴尔笔记本图纸
- 城市经济发展——城市化与第三产业的发展 考题答案
- matlab中1 1sym,请问为什么计算结果是sym 0x1
- 网页设计期末作业 使用HTML制作静态宠物网站——蓝色版爱宠之家(HTML CSS)
- 河南移动联合中兴打造SPNPTN网络融合示范样板