关于互斥量的基本概念:百度百科互斥量

推荐参考博客:秒杀多线程第七篇 经典线程同步 互斥量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多线程同步--互斥量的更多相关文章

  1. 总结windows多线程同步互斥

    windows多线程同步互斥--总结 我的windows多线程系列文章: windows多线程--原子操作 windows多线程同步--事件 windows多线程同步--互斥量 windows多线程同 ...

  2. windows多线程同步互斥--总结

    我的windows多线程系列文章: windows多线程--原子操作 windows多线程同步--事件 windows多线程同步--互斥量 windows多线程同步--临界区 windows多线程同步 ...

  3. 多线程面试题系列(7):经典线程同步 互斥量Mutex

    前面介绍了关键段CS.事件Event在经典线程同步问题中的使用.本篇介绍用互斥量Mutex来解决这个问题. 互斥量也是一个内核对象,它用来确保一个线程独占一个资源的访问.互斥量与关键段的行为非常相似, ...

  4. 秒杀多线程第七篇 经典线程同步 互斥量Mutex

    本文转载于:http://blog.csdn.net/morewindows/article/details/7470936 前面介绍了关键段CS.事件Event在经典线程同步问题中的使用.本篇介绍用 ...

  5. 转--- 秒杀多线程第七篇 经典线程同步 互斥量Mutex

    阅读本篇之前推荐阅读以下姊妹篇: <秒杀多线程第四篇一个经典的多线程同步问题> <秒杀多线程第五篇经典线程同步关键段CS> <秒杀多线程第六篇经典线程同步事件Event& ...

  6. 经典线程同步 互斥量Mutex

    阅读本篇之前推荐阅读以下姊妹篇: <秒杀多线程第四篇一个经典的多线程同步问题> <秒杀多线程第五篇经典线程同步关键段CS> <秒杀多线程第六篇经典线程同步事件Event& ...

  7. (转)经典线程同步 互斥量Mutex

    阅读本篇之前推荐阅读以下姊妹篇: <秒杀多线程第四篇一个经典的多线程同步问题> <秒杀多线程第五篇经典线程同步关键段CS> <秒杀多线程第六篇经典线程同步事件Event& ...

  8. windows多线程同步--临界区

    推荐参考博客:秒杀多线程第五篇 经典线程同步 关键段CS   关于临界区的观念,一般操作系统书上面都有. 适用范围:它只能同步一个进程中的线程,不能跨进程同步.一般用它来做单个进程内的代码快同步,效率 ...

  9. Linux多线程——使用互斥量同步线程

    前文再续,书接上一回,在上一篇文章: Linux多线程——使用信号量同步线程中,我们留下了一个如何使用互斥量来进行线程同步的问题,本文将会给出互斥量的详细解说,并用一个互斥量解决上一篇文章中,要使用两 ...

随机推荐

  1. bzoj1036点权模板题

    /* HYSBZ1036 树上有1-n个结点,每个节点都有一个权值w 操作 CHANGE u t:把结点u的权值改为t QMAX u v:询问从点u到v的路径上的节点的最大权值 QSUM u v:询问 ...

  2. 性能测试二:jmeter参数化+聚合报告

    一.参数化 1.随机数 2.随机字符串 二.文件 1.文本,csv_read (此方式同一个并发,永远只取一行数据,同一个并发,永远只使用同一个账户,如购物车下单) 2.CSV Data Set Co ...

  3. Nordic Collegiate Programming Contest NCPC 2017-Problem D-Distinctive Character

    题目大意:给你n(n<=1e5)个二进制串 (每个串位数不超过20),定义两个串的相似度为对应 位置上相同的个数. 让你构造一个二进制串,使这个串与所给的这些串的相似度的最小值最大. 思路:刚开 ...

  4. 被忽视的META标签之特效(页面过渡效果)

    在web设计中使用js可以实现很多的页面特效,然而很多人却忽视了HTML标签中META标签的强大功效,其实meta标签也可以实现很多漂亮的页面过渡效果. META标签是HTML语言HEAD区的一个辅助 ...

  5. 046 hiveserver2以及beeline客户端的使用

    一:开启服务 1.启动前端的hiveserver2 按住ctrl+c就可以结束这个服务. 2.怎么知道已经开启的服务 如果进程在后台,可以查出来,kill这些进程. 3.后端开启服务 二:beelin ...

  6. [OpenCV-Python] OpenCV 中的图像处理 部分 IV (二)

    部分 IVOpenCV 中的图像处理 OpenCV-Python 中文教程(搬运)目录 16 图像平滑 目标 • 学习使用不同的低通滤波器对图像进行模糊 • 使用自定义的滤波器对图像进行卷积(2D 卷 ...

  7. python tkinter-单选、多选

      单选按钮 tkinter.Radiobutton(root,text='a').pack() tkinter.Radiobutton(root,text='b').pack() tkinter.R ...

  8. POJ 1655 Balancing Act (求树的重心)【树形DP】(经典)

    <题目链接> 题目大意:给你一棵树,任意去除某一个点后,树被分成了几个联通块,则该点的平衡值为所有分成的连通块中,点数最大的那个,问你:该树所有点中,平衡值最小的那个点是什么? 解题分析: ...

  9. 第一次亲密接触MSF

    第一次亲密接触MSF Metasploit Framework介绍 Metasploit是一款开源安全漏洞检测工具,附带数百个已知的软件漏洞,并保持频繁更新.被安全社区冠以“可以黑掉整个宇宙”之名的强 ...

  10. 【java并发核心二】Exchanger的使用

    类 Exchanger 的功能可以使2个线程之间传输数据,比生产者/消费者模式方便. Exchanger类的结构很简单,重点就是exchange()方法. exchange()方法是阻塞执行的,可以设 ...