向我老大致敬!

这个做法其实是抄我老大的。服务器中,多线程经常需要使用临界区,为了简化代码的使用,把临界区封装为 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. iOS Programming - Views(视图 - 基本绘制,变换,平移,旋转,反转,倾斜)

    1. Views A view (an object whose class is UIView or a subclass of UIView) knows how to draw itself i ...

  2. java中Queue接口

    Queue接口与List.Set同一级别,都是继承了Collection接口.LinkedList实现了Queue接 口.Queue接口窄化了对LinkedList的方法的访问权限(即在方法中的参数类 ...

  3. tornado ThreadPoolExecutor

    import os import sys import time import tornado.httpserver import tornado.ioloop import tornado.opti ...

  4. Android Studio之基本设置与运行

    项目结构 当我们新建一个项目的目录结构默认是这样的 可以看到和Eclipse的目录结构有很大区别,Studio一个窗口只能有一个项目,而Eclipse则可以同时存在很多项目,如果你看着不习惯可以点击左 ...

  5. Java中abstract class 和 interface 的解释和他们的异同点(转)

    (一)概述    在Java语言中, abstract class 和interface 是支持抽象类定义的两种机制.正是由于这两种机制的存 在,才赋予了Java强大的 面向对象能力.abstract ...

  6. MySQL中 order by 与 limit 的执行顺序以及使用实例

    在 MySQL 执行查询的时候,我们可能既要对结果集进行排序又要限制行数,那么此时 order by 与 limit 的执行顺序是怎么样的呢? order by与limit的执行顺序是:先执行orde ...

  7. DEV 第三方控件报表分类汇总

    最近这段时间难得空闲,于是打算做个报表功能,主要实现数据的分类汇总,以便不时之需.首先看看效果: 主要是根据工程类型这个字段进行分类,每个分类下对应的项目金额进行求和,当然,你也可以根据实际需求,进行 ...

  8. oracle 复杂的查找用法

    [第一题]: 找到员工表中工资最高的前三名,要求按如下格式输出(第一步部分):以及oracle查询结果指定分页显示的方法(第二部分). ——涉及Top-N分析问题. 一般不在子查询中使用order b ...

  9. 使用Apache Jmeter进行并发压力测试

    http://blog.jassassin.com/2014/04/17/tools/jmeter/

  10. 英文版windows乱码问题(win7/8/10)