当前位置:网站首页>Multi-threaded mutex application RAII mechanism
Multi-threaded mutex application RAII mechanism
2022-07-30 20:02:00 【a ray of sunshine】
什么是RAII机制
RAII是Resource Acquisition Is Initialization(翻译成 “资源获取即初始化”)的简称,是C++语言的一种管理资源、To avoid resource leaks usage,The method is dependent on the constructor endowment and the destructor execution mechanism.
RAIIApproach is to use a class object,In the constructor of the object access to resources,在对象生命期内控制对资源的访问,Finally in the object disappears,Its destructor to release the access to resources;
这里的资源可以是文件句柄,内存,Event,互斥量等等,由于系统的资源是有限的,就好比自然界的石油,铁矿一样,不是取之不尽,用之不竭的.所以,We in programming security,Request must follow the following steps:
申请资源
使用资源
释放资源
In step 1 and step 2,We usually are relatively easy to grasp,And the release of resources will be overlooked because various coding,Lead to system resources not actually used,But not to release or cause other problems,Affect the system resource utilization.
没有使用RAII机制的弊端
So why do we involve resource management,建议使用RAIICoding mechanism?
You can view the code of the following two articles,I'm in these two articles are directly using the systemAPI进行资源操作,没有使用RAIIMechanism of resource management,In the code to read and maintain all very inconvenient.
Multithreaded deadlock and solve
Using the key code for thread synchronization
Don't recommend encoding clips:
while (TRUE)
{
//Wait until get the ownership of the specified object
EnterCriticalSection(&g_csLock);
//关键代码段-begin
if (g_nIndex++ < nMaxCnt)
{
cout << "Index = "<< g_nIndex << " ";
cout << "Thread2 is runing" << endl;
//权限释放,容易忘记
LeaveCriticalSection(&g_csLock);
}
else
{
//权限释放,容易忘记
LeaveCriticalSection(&g_csLock);
//关键代码段-end
break;
}
}
This encoding is not recommended becauseEnterCriticalSection/LeaveCriticalSection必须配对使用,Very need to rely on a person,Can't fundamentally solve the problem,如果LeaveCriticalSectionFunctions are not performed or forget to add theAPI很容易引发问题.
The mutex applicationRAII机制
为了从根本上解决问题,Reduce artificial factors causing application system problem or resource leak,The key code and the mutex lock both demonstrated how to applyRAII机制,Simplify the multi-threading mutex code.
Initialization and lock key code interface:
class CSLock
{
public:
CSLock()
{
//When the constructor to initialize the key code object,获取资源
InitializeCriticalSection(&m_csLock);
}
~CSLock()
{
//Released when the destructor for key code object allocation of all resources,释放资源
DeleteCriticalSection(&m_csLock);
}
//Objects within the life cycle of the management of resources(Lock/Unlock),使用资源
void Lock()
{
EnterCriticalSection(&m_csLock);
}
void Unlock()
{
LeaveCriticalSection(&m_csLock);
}
//Stop lock copy and assignment
private:
CSLock (const CSLock& );
CSLock& operator = (const CSLock&);
private:
CRITICAL_SECTION m_csLock;
};Create a mutex object and lock interface:
class CMutexLock
{
public:
CMutexLock()
{
m_hMutex = CreateMutex(NULL, FALSE, NULL);//获取资源
}
~CMutexLock()
{
CloseHandle(m_hMutex);//释放资源
}
void Lock()
{
WaitForSingleObject(m_hMutex, INFINITE);//使用资源
}
void Unlock()
{
ReleaseMutex(m_hMutex);//使用资源
}
//Stop lock copy and assignment
private:
CMutexLock(const CMutexLock&);
CMutexLock& operator= (const CMutexLock&);
private:
HANDLE m_hMutex;
};类模板对象,再一次使用RAIIManagement mechanism of lock objects take up and release,Suggest to simplify lock application,Implement automatic recycling resources
template<class T>
class CLockGuard
{
public:
CLockGuard(T& locker) :m_lockerObj(locker)
{
m_lockerObj.Lock();
}
~CLockGuard()
{
m_lockerObj.Unlock();
}
private:
T& m_lockerObj; //必须是引用类型 Ensure to use the global lock,否则锁不住
};具体示例:
#include "stdafx.h"
#include <iostream>
#include <string>
#include <Windows.h>
//创建全局锁,Ensure that the lock is a
CSLock g_csLock;
CMutexLock g_Mutex;
//全局数据
int g_nIndex = 0;
const int nMaxCnt = 30;
BOOL AddNum(int tid)
{
BOOL bRet = TRUE;
//RAII用法,创建lockObject at the same time performlock操作,Destructor after automatic callunlock操作,Avoid man-made missing
CLockGuard<CMutexLock> lock(g_Mutex);
if (g_nIndex++ < nMaxCnt)
{
std::cout << "Index = " << g_nIndex << " ";
std::cout << "thread " << tid << " is runing" << std::endl;
}
else
{
bRet = FALSE;
}
return bRet;
}
//线程函数1
DWORD WINAPI Thread1(LPVOID lpParameter)
{
while (true)
{
if (!AddNum(1))
{
break;
}
}
return 0;
}
//线程函数2
DWORD WINAPI Thread2(LPVOID lpParameter)
{
while (true)
{
if (!AddNum(2))
{
break;
}
}
return 0;
}
int _tmain(int argc, _TCHAR* argv[])
{
HANDLE harThread[2] = {NULL,NULL};
//创建新的线程
harThread[0] = CreateThread(NULL, 0, Thread1, NULL, 0, NULL);//立即执行
harThread[1] = CreateThread(NULL, 0, Thread2, NULL, 0, NULL);//立即执行
WaitForMultipleObjects(2, harThread, TRUE, INFINITE);
//良好的编码习惯
for (int i = 0; i < 2; i++)
{
CloseHandle(harThread[i]);
}
return 0;
}运行效果:
从输出结果上看,Our lock is effective,No confusion.这里使用了CLockGuardTemplate class to further simplify multithreaded code lock,Both realized the code reuse and guarantee the security coding.其实,This encoding inC++11中lock_guardHas been applied to the system.点击这里查看lock_guard(lock_guard - C++ Reference).
边栏推荐
- win2003下FTP服务器如何搭建
- 在jOOQ中获取数据的多种不同方式
- Recommended system: cold start problem [user cold start, item cold start, system cold start]
- 【PyTorchVideo教程01】快速实现视频动作识别
- MySQL复制表结构、表数据的方法
- SQLyog注释 添加 撤销 快捷键
- MindSpore:【resnet_thor模型】尝试运行resnet_thor时报Could not convert to
- Different lower_case_table_names settings for server (‘1‘) and data dictionary (‘0‘) 解决方案
- 牛客网——华为题库(100~108)
- 为单行查询设置JDBC Statement.setFetchSize()为1的方法指南
猜你喜欢

win2003下FTP服务器如何搭建

M3SDA:用于多源域自适应的矩匹配

Different lower_case_table_names settings for server (‘1‘) and data dictionary (‘0‘) 解决方案

从离线到实时对客,湖仓一体释放全量数据价值

MySQL eight-part text recitation version

PHP低代码开发引擎—表单设计

MindSpore:【MindSpore1.1】Mindspore安装后验证出现cudaSetDevice failed错误

银行数据资产转换能力弱?思迈特软件助力解决银行困境

mysql慢查询优化

MySQL mass production of data
随机推荐
MySQL mass production of data
MySQL数据库之JDBC编程
刷题记录----字符串
ERROR 1045 (28000) Access denied for user 'root'@'localhost'Solution
并发与并行的区别
ELK log analysis system
基于人脸的常见表情识别(1)——深度学习基础知识
【视频】极值理论EVT与R语言应用:GPD模型火灾损失分布分析
使用MULTISET来比较数据集的实例介绍
Start foreground Activity
el-input 只能输入整数(包括正数、负数、0)或者只能输入整数(包括正数、负数、0)和小数
Install Mysql5.7 under Linux, super detailed and complete tutorial, and cloud mysql connection
MySQL数据库 ---MySQL表的增删改查(进阶)
【PM专用】快速统计团队还有谁没有登记上报信息,快速筛选出属于自己项目组的成员,未完成XXX工作事项的名单
为单行查询设置JDBC Statement.setFetchSize()为1的方法指南
18.客户端会话技术Cookie
多线程的互斥锁应用RAII机制
Mac安装PHP开发环境
Day31 LeetCode
时间复杂度与空间复杂度