临界区(Critical Section)的封装和使用示例
向我老大致敬!
这个做法其实是抄我老大的。服务器中,多线程经常需要使用临界区,为了简化代码的使用,把临界区封装为 CThreadLockHandle 类,通过封装,使用临界区资源每次只需要一行代码,而且只要确定对象的生存周期,就能完成对临界区资源的自动释放:
头文件:
//thread_lock.h
#ifndef THREAD_LOCK_HEAD_FILE
#define THREAD_LOCK_HEAD_FILE
#include<windows.h>
//////////////////////////////////////////////////////////////////////////// //临界区同步类
class CThreadLock
{
//变量定义
private:
CRITICAL_SECTION m_csLock; //临界区变量 //函数定义
public:
//构造函数
inline CThreadLock() { ::InitializeCriticalSection(&m_csLock); };
//析构函数
inline ~CThreadLock() { ::DeleteCriticalSection(&m_csLock); }; //功能函数
public:
//锁定函数
inline void Lock() { ::EnterCriticalSection(&m_csLock); };
//解锁函数
inline void UnLock() { ::LeaveCriticalSection(&m_csLock); };
}; //////////////////////////////////////////////////////////////////////////// //安全同步锁定句柄
class CThreadLockHandle
{
//变量定义
private:
int m_nLockCount; //锁定计数
CThreadLock *m_pThreadLock; //锁定对象 //函数定义
public:
//构造函数
CThreadLockHandle(CThreadLock *pThreadLock, bool bAutoLock=true);
//析构函数
virtual ~CThreadLockHandle(); //功能函数
public:
//锁定函数
void Lock();
//解锁函数
void UnLock();
//火枪锁定次数
int inline GetLockCount() { return m_nLockCount; };
}; #endif
源文件:
//thread_lock.cpp programed by sany
//2014.9.2
//callme:sanyue9394@163.com #include "thread_lock.h"
#include<assert.h>
//////////////////////////////////////////////////////////////////////////// //安全同步锁定句柄
//构造函数
CThreadLockHandle::CThreadLockHandle(CThreadLock *pThreadLock, bool bAutoLock)
{
assert(pThreadLock!=NULL);
m_nLockCount=;
m_pThreadLock=pThreadLock;
if(bAutoLock) Lock();
return;
}
//析构函数
CThreadLockHandle::~CThreadLockHandle()
{
while(m_nLockCount>) UnLock(); //生存周期结束自动解锁
} //锁定函数
void CThreadLockHandle::Lock()
{
//校验状态
assert(m_nLockCount>=);
assert(m_pThreadLock!=NULL); //锁定对象
m_nLockCount++;
m_pThreadLock->Lock();
} //解锁函数
void CThreadLockHandle::UnLock()
{
//校验状态
assert(m_nLockCount>);
assert(m_pThreadLock!=NULL); //解除状态
m_nLockCount--;
m_pThreadLock->UnLock();
}
经过这个类的封装,使用临界区实现线程同步只需要2步:
1.初始化一个全局的 CThreadLock 对象,为后面调用做准备。
2.每当需要使用临界区时,在作用域中声明一个局部变量:CThreadLockHandle ,当其生存周期结束时,将自动释放临界区资源
使用例子:
#include<stdio.h>
#include<windows.h>
#include <process.h>
#include"thread_lock.h" const int aSize=;
char szArr[aSize+]={}; CThreadLock threadLock; //声明CThreadLock类型的全局变量 unsigned _stdcall threadFunc1(void*)
{
CThreadLockHandle lockHandle(&threadLock); //需要使用临界区是,声明一个CThreadLockHandle类型的变量,其生存周期结束自动解锁
for(int s=;s<aSize;s++)
{
szArr[s]='a';
Sleep();
}
return ;
} unsigned _stdcall threadFunc2(void*)
{
CThreadLockHandle lockHandle(&threadLock); //需要使用临界区是,声明一个CThreadLockHandle类型的变量,其生存周期结束自动解锁
for(int s=;s<aSize;s++)
{
szArr[aSize--s]='b';
Sleep();
}
return ;
} int main()
{
memset(szArr,,sizeof(szArr));
HANDLE handle1=(HANDLE)_beginthreadex(NULL,,threadFunc1,NULL,,);
HANDLE handle2=(HANDLE)_beginthreadex(NULL,,threadFunc2,NULL,,); WaitForSingleObject(handle1,INFINITE);
WaitForSingleObject(handle2,INFINITE); printf("%s\n",szArr);
CloseHandle(handle1);
CloseHandle(handle2); return ;
}
如果在类中调用,把CThreadLock 对象声明为私有或保护成员即可:
class threadtest
{
protected:
static CThreadLock m_ThreadLock; //线程锁 public:
static unsigned _stdcall threadFunction(void* pThreadData);
};
unsigned _stdcall threadtest::threadFunction(void* pThreadData)
{
CThreadLockHandle lockHandle(&m_ThreadLock); //生存周期结束自动解锁
//doSomething
return ;
}
附:http://www.cnblogs.com/userinterface/archive/2005/04/27/146137.html 不错的线程同步文章
临界区(Critical Section)的封装和使用示例的更多相关文章
- MFC线程(二):线程同步临界区CRITICAL SECTION
当多个线程同时使用相同的资源时,由于是并发执行,不能保证先后顺序.所以假如时一个公共变量被几个线程同时使用会造成该变量值的混乱. 下面来举个简单例子. 假如有一个字符数组变量 char g_charA ...
- 临界区代码 critical section Locks and critical sections in multiple threads
临界区 在同步的程序设计中,临界区段(Critical section)指的是一个访问共享资源(例如:共享设备或是共享存储器)的程序片段,而这些共享资源有无法同时被多个线程访问的特性. 当有线程进入临 ...
- 第4章 同步控制 Synchronization ----critical section 互斥区 ,临界区
本章讨论 Win32 同步机制,并特别把重点放在多任务环境的效率上.撰写多线程程序的一个最具挑战性的问题就是:如何让一个线程和另一个线程合作.除非你让它们同心协力,否则必然会出现如第2章所说的&quo ...
- critical section的用法
critical section Critical Section: 不论是硬件临界资源,还是软件临界资源,多个进程必须互斥地对它进行访问.每个进程中访问临界资源的那段代码称为临界区(Critical ...
- spinlock,mutex,semaphore,critical section的作用与差别
某年深信服的笔试题,考的就是多线程的同步.简单的解释下方便记忆: 1.spinlock:自旋锁.是专为防止多处理器并发而引入的一种锁. 2.mutex:相互排斥量. 仅仅有拥有相互排斥对象的线程才有訪 ...
- windows 下 Mutex和Critical Section 区别和使用
Mutex和Critical Section都是主要用于限制多线程(Multithread)对全局或共享的变量.对象或内存空间的访问.下面是其主要的异同点(不同的地方用黑色表示). Mutex Cri ...
- win32多线程 (二)线程同步之临界区 (critical sections)
所谓critical sections 意指一小块“用来处理一份被共享之资源”的程序代码.你可能必须在程序的许多地方处理这一块可共享的资源.所有这些程序代码可以被同一个critical sectio ...
- 【JMeter_09】JMeter逻辑控制器__临界部分控制器<Critical Section Controller>
临界部分控制器<Critical Section Controller> 业务逻辑: 根据锁名来控制并发,同一个锁名之下,在同一时间点只能存在一个运行中,适用于控制并发的场景 锁名类型: ...
- asp.net core封装layui组件示例分享
用什么封装?自然是TagHelper啊,是啥?自己瞅文档去 在学习使用TagHelper的时候,最希望的就是能有个Demo能够让自己作为参考 怎么去封装一个组件? 不同的情况怎么去实现? 有没有更好更 ...
随机推荐
- 【笔记】js原生方法 在元素外部或内部实现添加元素功能(类似jq 的 insert 和 append)
介绍的这个方法是:insetAdjacentHTML() 方法 此方法接收两个参数: 第一个参数必为下列值: beforebegin:在调用的元素外部的前面添加一个目标元素 afterend:在调用元 ...
- poj 1284 Primitive Roots(原根+欧拉函数)
http://poj.org/problem?id=1284 fr=aladdin">原根 题意:对于奇素数p,假设存在一个x(1<x<p),(x^i)%p两两不同(0&l ...
- Java补漏(一)
第一章前言 在学长的建议下,为了弥补之前学Java漏下的或者不是非常清楚的知识点,买了本蛮好的教科书-<Java学习笔记(JDK6)>,正式又一次学习.为了记下一些让我恍然大悟的知识 ...
- Maven中setting.xml配置Demo
<!-- 指定本地默认仓库 --> <localRepository>G:\Java\apache-maven-3.5.2\repository</localReposi ...
- 算法笔记_092:蓝桥杯练习 c++_ch04_02_修正版(Java)
目录 1 问题描述 2 解决方案 1 问题描述 [题目描述] 实现一个时间类Time.将小时,分钟和秒存储为int型成员变量.要求该类中包含一个构造函数,访问用的函数,一个推进当前时间的函数adv ...
- php 获取ip地址方法
function getIP() { $ip=""; if(!empty($_SERVER['HTTP_CLIENT_IP'])){ $myip = $_SERVER['HTTP_ ...
- Mysql 如何查询两个时间段之间的数据?
Mysql 如何查询两个时间段之间的数据?
- ionic 项目使用百度地图插件(cordova-qdc-baidu-location)
现在我们使用'Weizhe He'提供的cordova-qdc-baidu-location来尝试创建简单的定位app. Stpe1:创建一个项目 Stpe2:申请百度地图API秘钥 应用类型 ...
- HTML5中标记与特殊属性
不允许写结束标记的元素有(只允许<元素/>): area.base.br.col.command.embed.hr.img.input. keygen.link.meta.param.so ...
- 【微信小程序】loading标签使用,可自定义时长
前言:loading和wx.showToast的区别: wx.showToast加载的时间长度是需要手动设置的,默认1500ms,而loading标签则可以配合数据加载进行隐藏. 核心就是在数据量较大 ...