windows多线程同步--互斥量
关于互斥量的基本概念:百度百科互斥量
推荐参考博客:秒杀多线程第七篇 经典线程同步 互斥量Mutex
注意:互斥量也是一个内核对象,它用来确保一个线程独占一个资源的访问。互斥量与关键段的行为非常相似,并且互斥量可以用于不同进程中的线程互斥访问资源 本文地址
主要用到2个函数:CreateMutex,ReleaseMutex:
CreateMutex
函数功能:创建互斥量(注意与事件Event的创建函数对比)
函数原型:
HANDLE CreateMutex(
LPSECURITY_ATTRIBUTESlpMutexAttributes,
BOOLbInitialOwner,
LPCTSTRlpName
);
第一个参数:表示安全控制,一般直接传入NULL。
第二个参数:用来确定互斥量的初始拥有者。如果传入TRUE表示互斥量对象内部会记录创建它的线程的线程ID号并将递归计数设置为1,由于该线程ID非零,所以互斥量处于未触发状态。如果传入FALSE,那么互斥量对象内部的线程ID号将设置为NULL,递归计数设置为0,这意味互斥量不为任何线程占用,处于触发状态。
第三个参数:用来设置互斥量的名称,在多个进程中的线程就是通过名称来确保它们访问的是同一个互斥量。
返回值:成功则返回一个表示互斥量的句柄,失败返回NULL。
ReleaseMutex
功能:释放互斥量
函数原型:
BOOL ReleaseMutex (HANDLEhMutex)
函数说明:
访问互斥资源前应该要调用等待函数,结束访问时就要调用ReleaseMutex()来表示自己已经结束访问,其它线程可以开始访问了。
另外还有个函数OpenMutex 可以打开其它进程中创建的互斥量
注意:主线程不要忘了删除互斥量
下面从一个例子说明:假设有三个线程都需要使用打印机,我们可以使用互斥量来控制,这样就可以保证每次只有一个线程在使用打印机
#include<string>
#include<iostream>
#include<process.h>
#include<windows.h>
using namespace std; //声明互斥量句柄
HANDLE hmu; //线程绑定的函数返回值和参数是确定的,而且一定要__stdcall
unsigned __stdcall threadFun(void *param)
{
WaitForSingleObject(hmu, INFINITE);//等待互斥量
cout<<*(string *)(param)<<endl;
ReleaseMutex(hmu);//释放互斥量
return 1;
} int main()
{
//创建互斥量
hmu = CreateMutex(NULL, FALSE, NULL); HANDLE hth1, hth2, hth3;
string s1 = "first", s2 = "second", s3 = "third"; //创建线程
hth1 = (HANDLE)_beginthreadex(NULL, 0, threadFun, &s1, 0, NULL);
hth2 = (HANDLE)_beginthreadex(NULL, 0, threadFun, &s2, 0, NULL);
hth3 = (HANDLE)_beginthreadex(NULL, 0, threadFun, &s3, 0, NULL); //等待子线程结束
WaitForSingleObject(hth1, INFINITE);
WaitForSingleObject(hth2, INFINITE);
WaitForSingleObject(hth3, INFINITE); //一定要记得关闭线程句柄
CloseHandle(hth1);
CloseHandle(hth2);
CloseHandle(hth3); //千万别忘了删除互斥量
CloseHandle(hmu);
}
互斥量有没有和临界区一样具有所有权属性呢,我们也从相同的例子来看:编写一个程序,开启3个线程,这3个线程的ID分别为A、B、C,每个线程将自己的ID在屏幕上打印10遍,要求输出结果必须按ABC的顺序显示;如:ABCABC….依次递推。
#include<string>
#include<iostream>
#include<process.h>
#include<windows.h>
using namespace std;
//声明3个互斥量句柄
HANDLE hmu1, hmu2, hmu3; //线程绑定的函数返回值和参数是确定的,而且一定要__stdcall
unsigned __stdcall threadFunA(void *)
{
for(int i = 0; i < 10; i++){
WaitForSingleObject(hmu1, INFINITE);//等待互斥量
cout<<"A";
ReleaseMutex(hmu2);//释放互斥量
}
return 1;
}
unsigned __stdcall threadFunB(void *)
{
for(int i = 0; i < 10; i++){
WaitForSingleObject(hmu2, INFINITE);//等待互斥量
cout<<"B";
ReleaseMutex(hmu3);//释放互斥量
}
return 2;
}
unsigned __stdcall threadFunC(void *)
{
for(int i = 0; i < 10; i++){
WaitForSingleObject(hmu3, INFINITE);//等待互斥量
cout<<"C";
ReleaseMutex(hmu1);//释放互斥量
}
return 3;
} int main()
{
hmu1 = CreateMutex(NULL, FALSE, NULL);
hmu2 = CreateMutex(NULL, FALSE, NULL);
hmu3 = CreateMutex(NULL, FALSE, NULL); HANDLE hth1, hth2, hth3;
//创建线程
hth1 = (HANDLE)_beginthreadex(NULL, 0, threadFunA, NULL, 0, NULL);
hth2 = (HANDLE)_beginthreadex(NULL, 0, threadFunB, NULL, 0, NULL);
hth3 = (HANDLE)_beginthreadex(NULL, 0, threadFunC, NULL, 0, NULL); //等待子线程结束
WaitForSingleObject(hth1, INFINITE);
WaitForSingleObject(hth2, INFINITE);
WaitForSingleObject(hth3, INFINITE); //一定要记得关闭线程句柄
CloseHandle(hth1);
CloseHandle(hth2);
CloseHandle(hth3); //删除互斥量
CloseHandle(hmu1);
CloseHandle(hmu2);
CloseHandle(hmu3);
}
从结果看互斥量也具有所有权属性,即拥有互斥量的线程可以重复进入互斥量保护的区域
【版权声明】转载请注明出处:http://www.cnblogs.com/TenosDoIt/p/3601387.html
windows多线程同步--互斥量的更多相关文章
- 总结windows多线程同步互斥
windows多线程同步互斥--总结 我的windows多线程系列文章: windows多线程--原子操作 windows多线程同步--事件 windows多线程同步--互斥量 windows多线程同 ...
- windows多线程同步互斥--总结
我的windows多线程系列文章: windows多线程--原子操作 windows多线程同步--事件 windows多线程同步--互斥量 windows多线程同步--临界区 windows多线程同步 ...
- 多线程面试题系列(7):经典线程同步 互斥量Mutex
前面介绍了关键段CS.事件Event在经典线程同步问题中的使用.本篇介绍用互斥量Mutex来解决这个问题. 互斥量也是一个内核对象,它用来确保一个线程独占一个资源的访问.互斥量与关键段的行为非常相似, ...
- 秒杀多线程第七篇 经典线程同步 互斥量Mutex
本文转载于:http://blog.csdn.net/morewindows/article/details/7470936 前面介绍了关键段CS.事件Event在经典线程同步问题中的使用.本篇介绍用 ...
- 转--- 秒杀多线程第七篇 经典线程同步 互斥量Mutex
阅读本篇之前推荐阅读以下姊妹篇: <秒杀多线程第四篇一个经典的多线程同步问题> <秒杀多线程第五篇经典线程同步关键段CS> <秒杀多线程第六篇经典线程同步事件Event& ...
- 经典线程同步 互斥量Mutex
阅读本篇之前推荐阅读以下姊妹篇: <秒杀多线程第四篇一个经典的多线程同步问题> <秒杀多线程第五篇经典线程同步关键段CS> <秒杀多线程第六篇经典线程同步事件Event& ...
- (转)经典线程同步 互斥量Mutex
阅读本篇之前推荐阅读以下姊妹篇: <秒杀多线程第四篇一个经典的多线程同步问题> <秒杀多线程第五篇经典线程同步关键段CS> <秒杀多线程第六篇经典线程同步事件Event& ...
- windows多线程同步--临界区
推荐参考博客:秒杀多线程第五篇 经典线程同步 关键段CS 关于临界区的观念,一般操作系统书上面都有. 适用范围:它只能同步一个进程中的线程,不能跨进程同步.一般用它来做单个进程内的代码快同步,效率 ...
- Linux多线程——使用互斥量同步线程
前文再续,书接上一回,在上一篇文章: Linux多线程——使用信号量同步线程中,我们留下了一个如何使用互斥量来进行线程同步的问题,本文将会给出互斥量的详细解说,并用一个互斥量解决上一篇文章中,要使用两 ...
随机推荐
- graphql详解
随着系统业务量的增大不同的应用和系统共同使用着许多的服务api,而随着业务的变化和发展,不同的应用对相同资源的不同使用方法最终会导致需要维护的服务api数量呈现爆炸式的增长,比如我试着跑了下我们自己业 ...
- 在IDEA中实战Git
工作中多人使用版本控制软件协作开发,常见的应用场景归纳如下: 假设小组中有两个人,组长小张,组员小袁 场景一:小张创建项目并提交到远程Git仓库 场景二:小袁从远程git仓库上获取项目源码 场景三:小 ...
- 设计模式【转自JackFrost的博客】
首先,感谢作者对知识的分享 使用设计模式是为了可重用代码.让代码更容易被他人理解.保证代码可靠性.设计模式使代码编制真正工程化,是软件工程的基石脉络,如同大厦的结构一样. 文章结构:1.单一职责原则( ...
- MVC开发中的常见错误-07-“System.IO.DirectoryNotFoundException”类型的未经处理的异常在 mscorlib.dll 中发生
“System.IO.DirectoryNotFoundException”类型的未经处理的异常在 mscorlib.dll 中发生 其他信息: 未能找到路径“F:\Users\home\Docume ...
- java使用md5加密
代码: public String EncoderByMd5(String str) throws NoSuchAlgorithmException, UnsupportedEncodingExcep ...
- Spring整合Quartz实现动态定时器,相关api,定时器添加,删除,修改
一.版本说明 spring3.1以下的版本必须使用quartz1.x系列,3.1以上的版本才支持quartz 2.x,不然会出错. 原因:spring对于quartz的支持实现,org.springf ...
- 《LINQ技术详解C#》-4.LINQ到对象
public static string[] Presidents { get; } = { "Adams", "Arthur", "Buchanan ...
- requirejs模块路径配置问题
三种情况:一.设置data-main,没配置baseUrl,以data-main的文件为基准:二.设置data-main,配置baseUrl,baseUrl以值以引用require.js的HTML为基 ...
- phpstrom破解
lisence输入 2018/04/09 更新 license server:http://im.js.cn:8888 http://idea.iteblog.com/key.php 2018/0 ...
- 乐观锁和悲观锁及CAS实现
乐观锁与悲观锁 悲观锁:总是假设最坏的情况,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会阻塞直到它拿到锁.传统的关系型数据库里边就用到了很多这种锁机制, ...