欢迎访问 生活随笔!

生活随笔

当前位置: 首页 >

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

发布时间:2023/12/2 86 豆豆
生活随笔 收集整理的这篇文章主要介绍了 C 多线程的互斥锁应用RAII机制 小编觉得挺不错的,现在分享给大家,帮大家做个参考.

什么是RAII机制

RAII是Resource Acquisition Is Initialization(翻译成 “资源获取即初始化”)的简称,是C 语言的一种管理资源、避免资源泄漏的惯用法,该方法依赖构造函数资和析构函数的执行机制。

RAII的做法是使用一个类对象,在对象的构造函数中获取资源,在对象生命期内控制对资源的访问,最后在对象消失时,其析构函数来释放获取的资源;

这里的资源可以是文件句柄,内存,Event,互斥量等等,由于系统的资源是有限的,就好比自然界的石油,铁矿一样,不是取之不尽,用之不竭的。所以,我们在编程安全上,要求必须遵循以下几个步骤:

1. 申请资源

2. 使用资源

3. 释放资源

  • 在步骤一和步骤二上,我们平时都比较容易把握,而资源的释放会因为种种编码原因容易被忽略,导致系统资源实际没有使用了,但却没有释放或者引发其他问题,影响了系统资源利用率。

    没有使用RAII机制的弊端

    那么我们为什么涉及资源管理时,建议使用RAII机制进行编码呢?

    不推荐的编码方式片段:

    while (TRUE) {     //等待直到获得指定对象的所有权     EnterCriticalSection(&g_csLock);      //关键代码段-begin     if (g_nIndex  < nMaxCnt)     {         cout << "Index = "<< g_nIndex << " ";         cout << "Thread2 is runing" << endl;         //权限释放,容易忘记         LeaveCriticalSection(&g_csLock);     }     else     {         //权限释放,容易忘记         LeaveCriticalSection(&g_csLock);         //关键代码段-end         break;     }  }

    之所以不推荐这样的编码方式是因为EnterCriticalSection/LeaveCriticalSection必须配对使用,很需要依赖人,无法根本上解决问题,如果LeaveCriticalSection函数没有执行或者忘记添加该API很容易引发问题。

    互斥锁应用RAII机制

    为了从根本上解决问题,减少人为因素引发应用系统问题或者资源泄漏,在关键代码段和互斥量这两种锁上示范了如何应用RAII机制,简化多线程互斥编码。

    关键代码段初始化和锁接口:

    class CSLock{public:    CSLock()    {        //构造函数时初始化关键代码段对象,获取资源        InitializeCriticalSection(&m_csLock);    }~CSLock()    {        //析构函数时释放为关键代码段对象分配的所有资源,释放资源        DeleteCriticalSection(&m_csLock);    }  //生命周期内实现对象资源的管理(Lock/Unlock),使用资源    void Lock()    {        EnterCriticalSection(&m_csLock);    }void Unlock()    {        LeaveCriticalSection(&m_csLock);    }    //阻止锁的拷贝和赋值private:    CSLock (const CSLock& );    CSLock& operator  = (const CSLock&);private:    CRITICAL_SECTION m_csLock; };

    创建互斥量对象和锁接口:

    class CMutexLock{public:    CMutexLock()    {        m_hMutex = CreateMutex(NULL, FALSE, NULL);//获取资源    }~CMutexLock()    {        CloseHandle(m_hMutex);//释放资源    }void Lock()    {        WaitForSingleobject(m_hMutex, INFINITE);//使用资源    }void Unlock()    {        ReleaseMutex(m_hMutex);//使用资源    }    //阻止锁的拷贝和赋值private:    CMutexLock(const CMutexLock&);    CMutexLock& operator= (const CMutexLock&);private:    HANDLE  m_hMutex;};

    类模板对象,再一次使用RAII机制管理锁对象的占用和释放,建议简化锁的应用,实现资源的自动回收

    template<class T>class CLockGuard{public:    CLockGuard(T& locker) :m_lockerObj(locker)    {        m_lockerObj.Lock();    }~CLockGuard()    {        m_lockerObj.Unlock();    }private:

    总结

    以上是生活随笔为你收集整理的C 多线程的互斥锁应用RAII机制的全部内容,希望文章能够帮你解决所遇到的问题。

    如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。