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

推荐参考博客:秒杀多线程第七篇 经典线程同步 互斥量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. 设计模式【转自JackFrost的博客】

    首先,感谢作者对知识的分享 使用设计模式是为了可重用代码.让代码更容易被他人理解.保证代码可靠性.设计模式使代码编制真正工程化,是软件工程的基石脉络,如同大厦的结构一样. 文章结构:1.单一职责原则( ...

  2. MVC开发中的常见错误-07-“System.IO.DirectoryNotFoundException”类型的未经处理的异常在 mscorlib.dll 中发生

    “System.IO.DirectoryNotFoundException”类型的未经处理的异常在 mscorlib.dll 中发生 其他信息: 未能找到路径“F:\Users\home\Docume ...

  3. Lucene.Net简单例子-01

    前面已经简单介绍了Lucene.Net,下面来看一个实际的例子 1.1 引用必要的bll文件.这里不再介绍(Lucene.Net  PanGu  PanGu.HightLight  PanGu.Luc ...

  4. DDD领域模型数据访问权限之权限(十二)

    实现权限的领域对象:BAS_Permission public partial class BAS_Permission:AggreateRoot { private IRepository<B ...

  5. 如何将自己的Image镜像Push到Docker Hub

    首先需要一个docker官方账号 这里我添加了一个AspNetCore程序 通过创建了一个镜像(前面提过使用Dockerfile处理了) docker build -t dockertest . 首先 ...

  6. nexus私服常用设置

    https://www.jianshu.com/p/7a09915675d9 或许用得上. settings.xml <server> <!-- 服务器密码 --> <i ...

  7. 007 关于Spark下的第二种模式——standalone搭建

    一:介绍 1.介绍standalone Standalone模式是Spark自身管理资源的一个模式,类似Yarn Yarn的结构: ResourceManager: 负责集群资源的管理 NodeMan ...

  8. How to uninstall Maya on a Mac

    How to uninstall Maya on a Mac Products and versions covered  By:  Support Jun 15 2018 SHARE ADD TO ...

  9. Ubuntu python Compression requires the (missing) zlib module

    描述: 在Ubuntu中安装setuptools时出现   Compression requires the (missing) zlib module 解决方法步骤: ①Ubuntu下安装zlib: ...

  10. flask第十篇——url_for【3】

      继续url_for的知识点 # coding: utf-8 from flask import Flask, url_forimport flask app = Flask(__name__)   ...