临界区(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能够让自己作为参考 怎么去封装一个组件? 不同的情况怎么去实现? 有没有更好更 ...
随机推荐
- 安装程序集'' policy.8.0.microsoft.vc80.atl,type=''win32-
ThinkPad Bluetooth with Enhanced Data Rate II 软件 在Windows 7 64-bit 下无法安装完成,弹出窗口提示 :安装程序集''policy.8.0 ...
- .NET Framwork 之 源代码编译成托管代码托管代码合并成程序集
我们都知道,C#程序需要在 .NET Framework 的环境中运行. 一.程序运行所需的三个关键 1.IL(中间语言):编译器编译源代码时生成的代码. 2. Framework类库(Framewo ...
- vue - check-versions.js for child_process
webpack之类的配置文件. webpack.base.conf.js
- Hibernate关系映射(三) 多对多
一.使用用户User和Role实现多对多的示例 User.java,实现对Role的引用 package com.lxit.entity; import java.util.HashSet; impo ...
- 小程序show-confirm-bar完成按钮不能隐藏
<textarea>show-confirm-bar="false"></textarea> 不生效怎么办>? 改成 show-confir ...
- struts2 Action向JSP传值方式
1.通过属性getXXX()和setXXX()方式 Action类 public class Test { private String name; public String getName() { ...
- 征服 Ajax 应用程序的安全威胁
Ajax 构建于动态 HTML(DHTML)技术之上,其中包括如下这些最常见的技术: JavaScript :JavaScript 是一种脚本语言,在客户端 Web 应用程序中经常使用. 文档对象模型 ...
- 安装Windows Service总是发生异常!
打开VS2010 创建个windows服务应用程序!没有添加删除任何一行代码!然后按照下面的步骤 1. 将这个服务程序切换到设计视图2. 右击设计视图选择“添加安装程序”3. 切换到刚被添加的Proj ...
- springboot服务器部署方式
1.利用maven打包 maven project --> clean --> install 2.云服务器上启动 nohup java -jar /xxx/xxx/xxx.jar > ...
- hdu1010Tempter of the Bone(dfs+奇偶剪枝)
题目链接:pid=1010">点击打开链接 题目描写叙述:给定一个迷宫,给一个起点和一个终点.问是否能恰好经过T步到达终点?每一个格子不能反复走 解题思路:dfs+剪枝 剪枝1:奇偶剪 ...