博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
用C++和Windows的互斥对象(Mutex)来实现线程同步锁
阅读量:4338 次
发布时间:2019-06-07

本文共 2882 字,大约阅读时间需要 9 分钟。

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

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

Lock.h

#ifndef _Lock_H #define _Lock_H  #include 
//锁接口类 class IMyLock { public: virtual ~IMyLock() {} virtual void Lock() const = 0; virtual void Unlock() const = 0; }; //互斥对象锁类 class Mutex : public IMyLock { public: Mutex(); ~Mutex(); virtual void Lock() const; virtual void Unlock() const; private: HANDLE m_mutex; }; //锁 class CLock { public: CLock(const IMyLock&); ~CLock(); private: const IMyLock& m_lock; }; #endif

 Lock.cpp

#include "Lock.h"  //创建一个匿名互斥对象 Mutex::Mutex() {     m_mutex = ::CreateMutex(NULL, FALSE, NULL); } //销毁互斥对象,释放资源 Mutex::~Mutex() {     ::CloseHandle(m_mutex); }  //确保拥有互斥对象的线程对被保护资源的独自访问 void Mutex::Lock() const {     DWORD d = WaitForSingleObject(m_mutex, INFINITE); }  //释放当前线程拥有的互斥对象,以使其它线程可以拥有互斥对象,对被保护资源进行访问 void Mutex::Unlock() const {     ::ReleaseMutex(m_mutex); }  //利用C++特性,进行自动加锁 CLock::CLock(const IMyLock& m) : m_lock(m) {     m_lock.Lock(); }  //利用C++特性,进行自动解锁 CLock::~CLock() {     m_lock.Unlock(); }

 下边是测试代码MyLock.cpp

// MyLock.cpp : 定义控制台应用程序的入口点。//  #include 
#include
#include "Lock.h" using namespace std; //创建一个互斥对象 Mutex g_Lock; //线程函数 unsigned int __stdcall StartThread(void *pParam) { char *pMsg = (char *)pParam; if (!pMsg) { return (unsigned int)1; } //对被保护资源(以下打印语句)自动加锁 //线程函数结束前,自动解锁 CLock lock(g_Lock); for( int i = 0; i < 5; i++ ) { cout << pMsg << endl; Sleep( 500 ); } return (unsigned int)0; } int main(int argc, char* argv[]) { HANDLE hThread1, hThread2; unsigned int uiThreadId1, uiThreadId2; char *pMsg1 = "First print thread."; char *pMsg2 = "Second print thread."; //创建两个工作线程,分别打印不同的消息 //hThread1 = ::CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)StartThread, (void *)pMsg1, 0, (LPDWORD)&uiThreadId1); //hThread2 = ::CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)StartThread, (void *)pMsg2, 0, (LPDWORD)&uiThreadId2); hThread1 = (HANDLE)_beginthreadex(NULL, 0, &StartThread, (void *)pMsg1, 0, &uiThreadId1); hThread2 = (HANDLE)_beginthreadex(NULL, 0, &StartThread, (void *)pMsg2, 0, &uiThreadId2); //等待线程结束 DWORD dwRet = WaitForSingleObject(hThread1,INFINITE); if ( dwRet == WAIT_TIMEOUT ) { TerminateThread(hThread1,0); } dwRet = WaitForSingleObject(hThread2,INFINITE); if ( dwRet == WAIT_TIMEOUT ) { TerminateThread(hThread2,0); } //关闭线程句柄,释放资源 ::CloseHandle(hThread1); ::CloseHandle(hThread2); system("pause"); return 0; }

 

 

转载于:https://www.cnblogs.com/luochengor/archive/2012/06/07/2539854.html

你可能感兴趣的文章
P1313 计算系数
查看>>
NSString的长度比较方法(一)
查看>>
Azure云服务托管恶意软件
查看>>
My安卓知识6--关于把项目从androidstudio工程转成eclipse工程并导成jar包
查看>>
旧的起点(开园说明)
查看>>
生产订单“生产线别”带入生产入库单
查看>>
crontab导致磁盘空间满问题的解决
查看>>
java基础 第十一章(多态、抽象类、接口、包装类、String)
查看>>
Hadoop 服务器配置的副本数量 管不了客户端
查看>>
欧建新之死
查看>>
自定义滚动条
查看>>
APP开发手记01(app与web的困惑)
查看>>
笛卡尔遗传规划Cartesian Genetic Programming (CGP)简单理解(1)
查看>>
mysql 日期时间运算函数(转)
查看>>
初识前端作业1
查看>>
ffmpeg格式转换命令
查看>>
万方数据知识平台 TFHpple +Xpath解析
查看>>
Hive实现oracle的Minus函数
查看>>
秒杀多线程第四篇 一个经典的多线程同步问题
查看>>
RocketMQ配置
查看>>