龙盟编程博客 | 无障碍搜索 | 云盘搜索神器
快速搜索
主页 > 软件开发 > C/C++开发 >

C++中的RAII机制详解(3)

时间:2014-10-01 02:25来源:网络整理 作者:网络 点击:
分享到:
这个例子可以说是实际项目的一个模型,当多个进程访问临界变量时,为了不出现错误的情况,需要对临界变量进行加锁;上面的例子就是使用的Windows的

这个例子可以说是实际项目的一个模型,当多个进程访问临界变量时,为了不出现错误的情况,需要对临界变量进行加锁;上面的例子就是使用的Windows的临界区域实现的加锁。但是,在使用CRITICAL_SECTION时,EnterCriticalSection和LeaveCriticalSection必须成对使用,很多时候,经常会忘了调用LeaveCriticalSection,此时就会发生死锁的现象。当我将对CRITICAL_SECTION的访问封装到MyLock类中时,之后,我只需要定义一个MyLock变量,而不必手动的去显示调用LeaveCriticalSection函数。

上述的两个例子都是RAII机制的应用,理解了上面的例子,就应该能理解了RAII机制的使用了。

使用RAII的陷阱

在使用RAII时,有些问题是需要特别注意的。容我慢慢道来。

先举个例子:

复制代码 代码如下:

#include <iostream>
#include <windows.h>
#include <process.h>
 
using namespace std;
 
CRITICAL_SECTION cs;
int gGlobal = 0;
 
class MyLock
{
public:
    MyLock()
    {
        EnterCriticalSection(&cs);
    }
 
    ~MyLock()
    {
        LeaveCriticalSection(&cs);
    }
 
private:
    //MyLock(const MyLock &);
    MyLock operator =(const MyLock &);
};
 
void DoComplex(MyLock lock)
{
}
 
unsigned int __stdcall ThreadFun(PVOID pv) 
{
    MyLock lock;
    int *para = (int *) pv;
 
    // I need the lock to do some complex thing
    DoComplex(lock);
 
    for (int i = 0; i < 10; ++i)
    {
        ++gGlobal;
        cout<< "Thread " <<*para<<endl;
        cout<<gGlobal<<endl;
    }
    return 0;
}
 
int main()
{
    InitializeCriticalSection(&cs);
 
    int thread1, thread2;
    thread1 = 1;
    thread2 = 2;
 
    HANDLE handle[2];
    handle[0] = ( HANDLE )_beginthreadex(NULL , 0, ThreadFun, ( void*)&thread1, 0, NULL );
    handle[1] = ( HANDLE )_beginthreadex(NULL , 0, ThreadFun, ( void*)&thread2, 0, NULL );
    WaitForMultipleObjects(2, handle, TRUE , INFINITE );
    return 0;
}

这个例子是在上个例子上的基础上进行修改的。添加了一个DoComplex函数,在线程中调用该函数,该函数很普通,但是,该函数的参数就是我们封装的类。你运行该代码,就会发现,加入了该函数,对gGlobal全局变量的访问整个就乱了。你有么有想过,这是为什么呢?网上很多讲RAII的文章,都只是说了这个问题,但是没有说为什么,在这里,我好好的分析一下这里。

精彩图集

赞助商链接