用C++实现多线程Mutex锁(Win32)

AI权益加码!Claude Code、Cursor等20+工具免费用! 购周边限时加赠Coding Plan Lite,畅享主流AI工具!学习进阶更高效! 阅读详情

转自http://blog.csdn.net/chexlong/article/details/7051193

本文目的:用C++和Windows的互斥对象(Mutex)来实现线程同步锁。

    准备知识:1,内核对象互斥体(Mutex)的工作机理,WaitForSingleObject函数的用法,这些可以从MSDN获取详情; 2,当两个或更多线程需要同时访问一个共享资源时,系统需要使用同步机制来确保一次只有一个线程使用该资源。Mutex 是同步基元,它只向一个线程授予对共享资源的独占访问权。如果一个线程获取了互斥体,则要获取该互斥体的第二个线程将被挂起,直到第一个线程释放该互斥体。

    下边是我参考开源项目C++ Sockets的代码,写的线程锁类

Lock.h

[cpp]  view plain copy
  1. #ifndef _Lock_H  
  2. #define _Lock_H  
  3.   
  4. #include <windows.h>  
  5.   
  6. //锁接口类  
  7. class IMyLock  
  8. {  
  9. public:  
  10.     virtual ~IMyLock() {}  
  11.   
  12.     virtual void Lock() const = 0;  
  13.     virtual void Unlock() const = 0;  
  14. };  
  15.   
  16. //互斥对象锁类  
  17. class Mutex : public IMyLock  
  18. {  
  19. public:  
  20.     Mutex();  
  21.     ~Mutex();  
  22.   
  23.     virtual void Lock() const;  
  24.     virtual void Unlock() const;  
  25.   
  26. private:  
  27.     HANDLE m_mutex;  
  28. };  
  29.   
  30. //锁  
  31. class CLock  
  32. {  
  33. public:  
  34.     CLock(const IMyLock&);  
  35.     ~CLock();  
  36.   
  37. private:  
  38.     const IMyLock& m_lock;  
  39. };  
  40.   
  41.   
  42. #endif  


Lock.cpp

[cpp]  view plain copy
  1. #include "Lock.h"  
  2.   
  3. //创建一个匿名互斥对象  
  4. Mutex::Mutex()  
  5. {  
  6.     m_mutex = ::CreateMutex(NULL, FALSE, NULL);  
  7. }  
  8.   
  9. //销毁互斥对象,释放资源  
  10. Mutex::~Mutex()  
  11. {  
  12.     ::CloseHandle(m_mutex);  
  13. }  
  14.   
  15. //确保拥有互斥对象的线程对被保护资源的独自访问  
  16. void Mutex::Lock() const  
  17. {  
  18.     DWORD d = WaitForSingleObject(m_mutex, INFINITE);  
  19. }  
  20.   
  21. //释放当前线程拥有的互斥对象,以使其它线程可以拥有互斥对象,对被保护资源进行访问  
  22. void Mutex::Unlock() const  
  23. {  
  24.     ::ReleaseMutex(m_mutex);  
  25. }  
  26.   
  27. //利用C++特性,进行自动加锁  
  28. CLock::CLock(const IMyLock& m) : m_lock(m)  
  29. {  
  30.     m_lock.Lock();  
  31. }  
  32.   
  33. //利用C++特性,进行自动解锁  
  34. CLock::~CLock()  
  35. {  
  36.     m_lock.Unlock();  
  37. }  


    下边是测试代码

[cpp]  view plain copy
  1. // MyLock.cpp : 定义控制台应用程序的入口点。  
  2. //  
  3.   
  4. #include <iostream>  
  5. #include <process.h>  
  6. #include "Lock.h"  
  7.   
  8. using namespace std;  
  9.   
  10. //创建一个互斥对象  
  11. Mutex g_Lock;  
  12.   
  13.   
  14. //线程函数  
  15. unsigned int __stdcall StartThread(void *pParam)  
  16. {  
  17.     char *pMsg = (char *)pParam;  
  18.     if (!pMsg)  
  19.     {  
  20.         return (unsigned int)1;  
  21.     }  
  22.   
  23.     //对被保护资源(以下打印语句)自动加锁  
  24.     //线程函数结束前,自动解锁  
  25.     CLock lock(g_Lock);  
  26.   
  27.     forint i = 0; i < 5; i++ )  
  28.     {  
  29.         cout << pMsg << endl;  
  30.         Sleep( 500 );  
  31.     }  
  32.   
  33.     return (unsigned int)0;  
  34. }  
  35.   
  36. int main(int argc, char* argv[])  
  37. {  
  38.     HANDLE hThread1, hThread2;  
  39.     unsigned int uiThreadId1, uiThreadId2;  
  40.   
  41.     char *pMsg1 = "First print thread.";  
  42.     char *pMsg2 = "Second print thread.";  
  43.   
  44.     //创建两个工作线程,分别打印不同的消息  
  45.   
  46.     //hThread1 = ::CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)StartThread, (void *)pMsg1, 0, (LPDWORD)&uiThreadId1);  
  47.     //hThread2 = ::CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)StartThread, (void *)pMsg2, 0, (LPDWORD)&uiThreadId2);  
  48.   
  49.     hThread1 = (HANDLE)_beginthreadex(NULL, 0, &StartThread, (void *)pMsg1, 0, &uiThreadId1);  
  50.     hThread2 = (HANDLE)_beginthreadex(NULL, 0, &StartThread, (void *)pMsg2, 0, &uiThreadId2);  
  51.   
  52.     //等待线程结束  
  53.     DWORD dwRet = WaitForSingleObject(hThread1,INFINITE);  
  54.     if ( dwRet == WAIT_TIMEOUT )  
  55.     {  
  56.         TerminateThread(hThread1,0);  
  57.     }  
  58.     dwRet = WaitForSingleObject(hThread2,INFINITE);  
  59.     if ( dwRet == WAIT_TIMEOUT )  
  60.     {  
  61.         TerminateThread(hThread2,0);  
  62.     }  
  63.   
  64.     //关闭线程句柄,释放资源  
  65.     ::CloseHandle(hThread1);  
  66.     ::CloseHandle(hThread2);  
  67.   
  68.     system("pause");  
  69.     return 0;  
  70. }  


    用VC2005编译,启动程序,下边是截图

 

    如果将测线程函数中的代码注视掉,重新编译代码,运行

[cpp]  view plain copy
  1. CLock lock(g_Lock);  

     则结果见下图

 

    由此可见,通过使用Mutex的封装类,即可达到多线程同步的目的。因Mutex属于内核对象,所以在进行多线程同步时速度会比较慢,但是用互斥对象可以在不同进程的多个线程之间进行同步。

    在实际应用中,我们通常还会用到临界区,也有叫做关键代码段的CRITICAL_SECTION,在下篇博客中,我将会把CRITICAL_SECTION锁添加进来,并且对Mutex和CRITICAL_SECTION的性能做以比较。


C++多线程同步之Mutex(互斥量) 一、互斥量Mutex同步多线程1、Win32平台相关函数和头文件#include <windows.h> HANDLE CreateMutex( LPSECURITY_ATTRIBUTESlpMutexAttributes, // 指向安全属性的指针 BOOLbInitialOwner, // 初始化互斥对象的所有者 LPCTSTRlpName // 指向互斥对象名的指针 );DWORD WINAP 阅读详情

相关推荐

C++多线程初探:thread、atomic及mutex的配合使用

不同OS下的多线程方案 线程相关的一些概念的说明 进程与线程的关系 线程的同步与线程安全 举个在多线程环境中公共变量访问出错的例子 C++中的解决办法 join及detach 参考资料 不同OS下的多线程方案 C/C++多线程编程在啊不同操作系统下有不同函数库可以进行调用,在Linux平台下,POSIX多线程库是,在windows平台下,有windows API...

yucicheung的博客 2075

windowsC++多线程信号量共享内存

windowsC++多线程信号量共享内存

windows下线程

windows下的多线程机制

【转】用C++实现多线程MutexWin32

原作者:chexlong原文地址:http://blog.csdn.net/chexlong/article/details/7051193 本文目的:用C++和Windows的互斥对象(Mutex)来实现线程同步。 准备知识:1,内核对象互斥体(Mutex)的工作机理,WaitForSingleObject函数的用法,这些可以从MSDN获取详情;2,当两个或更多线程需要同时访问...

weixin_34406061的博客 160

【Window】线程中的几种

第一节:【Window】创建线程的3种方式 第二节:【Window】线程同步概述 第三节:【Window】线程同步方式1——临界区(关键代码段) 第四节:【Window】线程同步方式2——互斥量 第五节:【Window】线程同步方式3——事件 第六节:【Window】线程同步方式4——信号量 第七节:【Window】线程同步方式4——信号量 第八节:【Window】互斥——Mutex,lock_guard,unique_lock 线程之间的有: 互斥 条件 自旋 读写 递归 一般而言,

WaitFoF 1354

【学习笔记】Windows 下线程同步之互斥

简介:互斥是一种同步对象,当没有任何线程拥有互斥时,互斥处于有信号(signaled)状态,当互斥被某个线程拥有,则它处于无信号状态(nonsignaled)特点任何一个互斥,一次只能被一个线程拥有可以跨进程使用,即进程间同步适用场景:同步一些共享资源,比如共享内存(shared memory)

码的世界 2347

windows线程 互斥CreateMutex、ReleaseMutex、CloseHandle

windows线程 互斥CreateMutex、ReleaseMutex、CloseHandle

单于的学习历程 1679

互斥对象和临界区性能比较

Win32平台上进行多线程编程,常会用到。下边用C++实现了互斥对象(Mutex和临界区(CRITICAL_SECTION),以加深理解和今后方便使用。代码已在VS2005环境下编译测试通过。 Lock.h [cpp] view plaincopy #ifndef _Lock_H   #define _Lock_H      #in

公众呺:Linux兵工厂, 加关+私信获取海量Linux干货资料和代码 585

C++的线程读写(windows实现

/** * 读写 * 读-读并发,读-写互斥,写-写互斥 * Windows NT下可以使用 * 基于CRITICAL_SECTION实现,简单高效,只支持在进程内使用,不支持进程间使用 * 支持限制最大并发读者数 * 写操作优先(即当前有线程在读,有写操作后,不允许再有新的读,直至写操作完成,避免写操作饿死) * 直接加写才是写优先状态,采用尝试写是非写优先的 * @version 1.1 */ 附带有使用的例子……

【转】Win32下两种用于C++的线程同步类(下)

Win32 c++ 线程同步 上一篇中我介绍了一种通过封闭Critical Section对象而方便的使用互斥的方式,文中所有的例子是两个线程对同一数据一读一写,因此需要让它们在这里互斥,不能同时访问。而在实际情况中可能会有更复杂的情况出现,就是多个线程访问同一数据,一部分是读,一部分是写。我们知道只有读-写或写-写同时进行时可能会出现问题,而读-读则可以同时进行,...

awk0656897的博客 134

同步阻塞模型的技术解析与应用

摘要:同步阻塞模型是MSVC平台的基础编程范式,通过线程主动等待机制实现资源访问控制。该模型采用Win32API同步原语(如互斥、信号量)和CRT库函数实现,适用于多线程管理、文件I/O及网络通信等场景。虽然实现简单但存在性能瓶颈,可通过粒度优化、无编程等技术提升效率。MSVC提供调试工具链支持,并逐步融合C++标准库特性(如协程、并行算法)作为现代替代方案。开发中需注意死预防和线程竞争问题,未来趋势将向异构计算和细粒度并发控制发展。(149字)

u010032977的专栏 297

c++多线程中“”的基本用法

c++多线程中“”的基本用法 1. mutex ,是生活中应用十分广泛的一种工具。的本质属性是为事物提供“访问保护”,例如:大门上的,是为了保护房子免于不速之客的到访;自行车的,是为了保护自行车只有owner才可以使用;保险柜上的,是为了保护里面的合同和金钱等重要东西…… 在c++等高级编程语言中,也是用来提供“访问保护”的,不过被保护的东西不再是房子、自行车、金钱,而是内存中的各种变量。此外,计算机领域对于“”有个响亮的名字——mutex(互斥量),学过操作系统的同学对这个名字肯定很

Michael Tian的博客 5909
上一篇: 单例模式——C++实现自动释放单例类的实例
下一篇: 白盒测试和黑盒测试
SHForWork
博客等级 码龄12年 11粉丝 6原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值