向我老大致敬!

这个做法其实是抄我老大的。服务器中,多线程经常需要使用临界区,为了简化代码的使用,把临界区封装为 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)的封装和使用示例的更多相关文章

  1. MFC线程(二):线程同步临界区CRITICAL SECTION

    当多个线程同时使用相同的资源时,由于是并发执行,不能保证先后顺序.所以假如时一个公共变量被几个线程同时使用会造成该变量值的混乱. 下面来举个简单例子. 假如有一个字符数组变量 char g_charA ...

  2. 临界区代码 critical section Locks and critical sections in multiple threads

    临界区 在同步的程序设计中,临界区段(Critical section)指的是一个访问共享资源(例如:共享设备或是共享存储器)的程序片段,而这些共享资源有无法同时被多个线程访问的特性. 当有线程进入临 ...

  3. 第4章 同步控制 Synchronization ----critical section 互斥区 ,临界区

    本章讨论 Win32 同步机制,并特别把重点放在多任务环境的效率上.撰写多线程程序的一个最具挑战性的问题就是:如何让一个线程和另一个线程合作.除非你让它们同心协力,否则必然会出现如第2章所说的&quo ...

  4. critical section的用法

    critical section Critical Section: 不论是硬件临界资源,还是软件临界资源,多个进程必须互斥地对它进行访问.每个进程中访问临界资源的那段代码称为临界区(Critical ...

  5. spinlock,mutex,semaphore,critical section的作用与差别

    某年深信服的笔试题,考的就是多线程的同步.简单的解释下方便记忆: 1.spinlock:自旋锁.是专为防止多处理器并发而引入的一种锁. 2.mutex:相互排斥量. 仅仅有拥有相互排斥对象的线程才有訪 ...

  6. windows 下 Mutex和Critical Section 区别和使用

    Mutex和Critical Section都是主要用于限制多线程(Multithread)对全局或共享的变量.对象或内存空间的访问.下面是其主要的异同点(不同的地方用黑色表示). Mutex Cri ...

  7. win32多线程 (二)线程同步之临界区 (critical sections)

    所谓critical sections 意指一小块“用来处理一份被共享之资源”的程序代码.你可能必须在程序的许多地方处理这一块可共享的资源.所有这些程序代码可以被同一个critical  sectio ...

  8. 【JMeter_09】JMeter逻辑控制器__临界部分控制器<Critical Section Controller>

    临界部分控制器<Critical Section Controller> 业务逻辑: 根据锁名来控制并发,同一个锁名之下,在同一时间点只能存在一个运行中,适用于控制并发的场景 锁名类型: ...

  9. asp.net core封装layui组件示例分享

    用什么封装?自然是TagHelper啊,是啥?自己瞅文档去 在学习使用TagHelper的时候,最希望的就是能有个Demo能够让自己作为参考 怎么去封装一个组件? 不同的情况怎么去实现? 有没有更好更 ...

随机推荐

  1. Android-标题状态栏的隐藏

    以下有两种方法,建议使用第一种方法:使用第一种方法,仅仅只需要在Manifest.xml文件中进行一行的配置就行了而且Activity在启动的时候也不会看到那个Title栏第一种方法:在配置文件中进行 ...

  2. 文本域光标操作(选、添、删、取)的jQuery扩展

    ; (function ($) { /* * 文本域光标操作(选.添.删.取)的jQuery扩展 @Mr.Think http://mrthink.net/text-field-jquery-exte ...

  3. asp.net页面生命周期之页面的终结阶段

    处理过回发事件之后,页面便为浏览器生成输出做好了准备.呈现阶段分为两部分:预呈现和标记生成.预呈现这个子阶段有两个事件表征,分别为:预处理和投递处理. PreRender事件 通过处理该事件,页面和控 ...

  4. Cocos2d-x中点九图(Scale9Sprite)创建图片按钮

    1. 配置引擎根目录支持 C/C++->常规->附加包含目录->增加->$(EngineRoot) 2. 引入头文件 #include "cocos-ext.h&qu ...

  5. lua coroutine

    Lua中协程都放在表coroutine中. Lua协程的四个状态 挂起(suspended):一个协程被创建的时候,处于挂起状态,不会自动运行. 运行(running):coroutine.resum ...

  6. C#计算时间间隔的方法小结

    初始化两个时间变量用于演示实例. DateTime dt1 = new DateTime(2013, 10, 13, 19, 15, 50); DateTime dt2 = new DateTime( ...

  7. 用C开发PHP扩展 实例(基础版)

    第一步:建立扩展骨架. cd /usr/local/src/php-5.3.6/ext/ ./ext_skel --extname=laiwenhui 第二步:修改编译参数. cd php-5.3.6 ...

  8. CDN新应用和客户

    目前的CDN配置服务主要应用于证券.金融保险.ISP.ICP.网上交易.门户网站.大中型公司.网络教学等领域.另外在行业专网.互联网中都可以用到,甚至可以对局域网进行网络优化.利用CDN,这些网站无需 ...

  9. iOS多线程之NSOperation和NSOperationQueue的使用

    一:NSOperation 两个子类+重写main方法 NSInvocationOperation NSBlockOperation 有个类方法 BlockOprationWith: 还有就是自己个子 ...

  10. bitbucket git push 项目503失败

    忙活了一天,要把项目push到远程仓库保存: 一直稳定的bitbucket今天突然push不成功了,出了503错误 谷歌了各种原因,还以为是连接出了问题 打开bitbucket State 页面之后, ...