用RAII的思想去管理Windows的读写锁SRWLock

Posted CodeBowl

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了用RAII的思想去管理Windows的读写锁SRWLock相关的知识,希望对你有一定的参考价值。

前言

最近对C++的RAII(资源申请初始化),又有了新的理解。

我们C++中使用一个资源(例如 内存)的步骤:

  1. 申请资源
  2. 使用资源
  3. 释放资源

简述一下RAII:

就是可以自动回收资源,将资源封装成对象。

关键在于:
变量的生命周期结束后,会自动释放变量。
例如一个变量是局部变量,存储在栈上,那么当该函数结束后,这个变量就已经被释放掉了。
那么,当变量是类变量的时候,当该类对象变量生命周期结束后,应该调用析构函数释放掉该资源!

生命周期

局部变量:存储在栈上,生命周期结束后,由栈释放。
全局或静态变量:存储在data段,生命周期是整个进程,自动释放。
堆上对象:存储在堆上,生命周期结束后,由编程人员释放。

我们申请内存的时候,就是在申请堆上的资源,所以需要我们手动释放,当我们忘记释放的时候,就会引起内存泄漏!

那么我们通过RAII的思想就可以解决这个问题!
使用栈上对象管理堆上的对象,通过析构函数,就可以确定资源释放的实际!

RAII 举例

实际上智能指针就是利用了RAII的思想。
这里简述一下:
构造函数申请指针资源,然后进行使用,当生命周期结束,析构函数会释放资源!

template<class T>
class smart_ptr

public:
	smart_ptr()(T* ptr = nullptr)
		:_ptr(ptr)
	
		// 构造函数
	
	~smart_ptr()
	
		// 析构函数
		if (_ptr)
			delete _ptr;
	
	//智能指针的第二个特性
	T& operator*()
	
		return *_ptr;
	
	T* operator->()
	
		return _ptr;
	
private:
	T* _ptr;

使用RAII的思想管理Windows的读写锁

#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 ) // 非常感谢益可达犀利的review 2014.04.13



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;



这个例子可以说是实际项目的一个模型,当多个进程访问临界变量时,为了不出现错误的情况,需要对临界变量进行加锁;上面的例子就是使用的Windows的临界区域实现的加锁。

但是,在使用CRITICAL_SECTION时,EnterCriticalSection和LeaveCriticalSection必须成对使用,很多时候,经常会忘了调用LeaveCriticalSection,此时就会发生死锁的现象。当我将对CRITICAL_SECTION的访问封装到MyLock类中时,之后,我只需要定义一个MyLock变量,而不必手动的去显示调用LeaveCriticalSection函数。

作者:DayDayUpppppp
链接:https://www.jianshu.com/p/b7ffe79498be
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

优点

这样的优点就是
第一:你不需要担心忘记释放资源,而引起的问题
第二:使用起来更加简单,只需要用,不用管释放的问题

参考资料

C++中的RAII机制

以上是关于用RAII的思想去管理Windows的读写锁SRWLock的主要内容,如果未能解决你的问题,请参考以下文章

线程间使用SRW轻量级锁共享变量

使用 WinDbg 查找谁持有本机进程的 SRW 锁

C++基于RAII对锁进行封装

C++基于RAII对锁进行封装

多线程的互斥锁应用RAII机制

多线程的互斥锁应用RAII机制