InterlockedIncrement和InterlockedDecrement的妙用

一般来说,在多用户线程环境中,我们使用临界区、事件对象甚至互斥量来进行同步,尤其是临界区,可以很方便地对某些变量甚至代码块进行锁定执行,防止多线程之间资源恶性抢夺。既然如此,为啥微软又单独提供了专用于一个数值锁定计算的API函数InterlockedIncrement和InterlockedDecrement呢?他们又有什么特殊作用呢?
    恰好近段时间写了一个这方面的应用,帮我加深了对这类API函数的理解。
    首先描述一下需求,在应用中,有这样一个类,它可能只被实例化一次,也可能会被实例化多次,但不管被实例化了几次,它必须在构造函数里执行一项初始化计算,假设初始化计算的函数为WSAStartup,同时还需要在析构函数里执行一下注销计算,假设注销计算的函数为WSACleanup,现在有一个要求,就是它们的初始化和注销计算只能被执行一次,就如同在一个项目中,只能运行一次WSAStartup和WSACleanup一样。当然,大家可能会想到直接在工程的开始和结尾处实现这样的功能,但是,如果把这个类的文件包括在其它测试工程里进行测试,同时不改变其它工程的代码,又该如何实现呢?
    其实,我们可以充分利用InterlockedIncrement和InterlockedDecrement,就如同COM的CoInitialize()和CoUninitialize()一样,描述代码如下:

    假设类名为A:

view plaincopy to clipboardprint?
class A  
{  
protected:  
    static long     m_nRef;  
public:  
    //类A的构造函数  
    A()  
    {  
        if(1 == InterlockedIncrement(&m_nRef))  
        {  
            //以下代码只执行一次  
            WSADATA wsaData;  
            WSAStartup(MAKEWORD(2,2), &wsaData);  
        }  
    };  
 
    //类A的虚析构函数  
    virtual ~A()  
    {  
        if(0 == InterlockedDecrement(&m_nRef))  
        {  
            //以下代码只执行一次  
            WSACleanup();  
        }  
    }  
};  
long A::m_nRef = 0; 
class A
{
protected:
 static long  m_nRef;
public:
 //类A的构造函数
 A()
 {
  if(1 == InterlockedIncrement(&m_nRef))
  {
   //以下代码只执行一次
   WSADATA wsaData;
   WSAStartup(MAKEWORD(2,2), &wsaData);
  }
 };

 //类A的虚析构函数
 virtual ~A()
 {
  if(0 == InterlockedDecrement(&m_nRef))
  {
   //以下代码只执行一次
   WSACleanup();
  }
 }
};
long A::m_nRef = 0;
 

    这样,无论我们创建了类A的多少个实例,在类的构造函数和析构函数里,WSAStartup和WSACleanup均只被执行一次,有效地保证了单元代码的封装性。

 

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/lyserver/archive/2010/02/04/5289265.aspx

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
Interlocked是一组Windows API,提供了一些原子操作,可以保证在执行时不会被其他线程中断,从而确保了线程安全。它通常用于保护共享资源,防止并发访问时出现竞争条件。 以下是Interlocked的一些常用函数: 1. InterlockedIncrement:原子地将指定变量的值加一。 ```C++ LONG InterlockedIncrement(LONG volatile *lpAddend); ``` 2. InterlockedDecrement:原子地将指定变量的值减一。 ```C++ LONG InterlockedDecrement(LONG volatile *lpAddend); ``` 3. InterlockedExchange:原子地将指定变量的值设置为一个新值,并返回旧值。 ```C++ LONG InterlockedExchange(LONG volatile *Target, LONG Value); ``` 4. InterlockedCompareExchange:原子地比较指定变量的值和期望值,并在它们相等时将变量的值设置为一个新值,返回旧值。 ```C++ LONG InterlockedCompareExchange(LONG volatile *Destination, LONG Exchange, LONG Comparand); ``` 使用Interlocked的一般步骤如下: 1. 定义一个变量,用于存储共享资源的值。 ```C++ LONG g_sharedVariable = 0; ``` 2. 在访问共享资源的地方使用Interlocked函数。 ```C++ InterlockedIncrement(&g_sharedVariable); ``` 以上代码实现了对共享变量g_sharedVariable的原子增量操作。 需要注意的是,Interlocked函数使用时需要将变量的指针传入函数中,而且变量必须是volatile类型的,以确保编译器不会对变量进行优化,从而造成不必要的错误。 另外,Interlocked函数的执行是原子性的,不会被其他线程中断,因此可以保证线程安全。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值