effective c++条款14

1.复制RAII对象必须一并复制它所管理的资源,所以资源的copying行为决定RAII对象的copying行为
2.普遍而常见的的RAII class copying行为是:抑制copying,施行引用计数法

第1条的意思是:我们要根据资源的copying行为去选择所用的管理类,
比如,
我之前有个类

class Lock
{
public:
    explicit Lock(mutex* pm):mutexPtr(pm){mutexPtr->lock();}
    ~Lock() {mutexPtr->unlock();}
private:
    mutex* mutexPtr;
}

这个类其实就是实现互斥量的锁定和解锁,但是如果要copy呢
1.禁止复制,这对互斥量来说其实还是很合理的
2.采用引用计数,引用计数就是复制时并不增加资源的数量,增加计数,当计数为0时,释放资源

我们这里考虑mutex的copying行为,决定采用shared_ptr嵌套Lock类,定义新的管理类,顺便说下,shared_ptr可以自定义自己的删除器
这是修改后的代码

void unlock(mutex* pm);
class Lock
{
public:
    explicit Lock(mutex* pm) :MutexPtr(pm, unlock){ MutexPtr.get()->lock(); }//这里我们把unlock定义为删除器,所以就不需要析构函数了
private:
    shared_ptr<mutex> MutexPtr;
};
void unlock(mutex* pm)
{
    pm->unlock();
}

再找个例子

#include<windows.h>
#include <iostream>
#include <memory>
#include <string>
#include<process.h>
#include<stdlib.h>
#include<vector>
#include <mutex>
using namespace std;
vector<int> g_vec;
HANDLE g_read, g_write;
//HANDLE hMutex;
mutex mx;
unsigned int WINAPI WorkThreadRead(void* param);
unsigned int WINAPI WorkThreadWrite(void* param);
void unlock(mutex* pm);
class Lock
{
public:
    explicit Lock(mutex* pm) :MutexPtr(pm, unlock){ MutexPtr.get()->lock(); }
private:
    shared_ptr<mutex> MutexPtr;
};

int main()
{
    //hMutex = CreateMutex(NULL, true, NULL);
    g_read = (HANDLE)_beginthreadex(NULL, 0, WorkThreadRead, NULL, 0, NULL);
    g_write = (HANDLE)_beginthreadex(NULL, 0, WorkThreadWrite, NULL, 0, NULL);
    CloseHandle(g_read);
    CloseHandle(g_write);
    system("pause");
    return 0;
}

unsigned int WINAPI WorkThreadRead(void* param)
{
    while (true)
    {
        Lock a(&mx);
        //WaitForSingleObject(hMutex, INFINITE);
        for (vector<int>::iterator it = g_vec.begin(); it != g_vec.end(); ++it)
        {
            cout << (*it) << endl;
        }
        //ReleaseMutex(hMutex);
    }
}

unsigned int WINAPI WorkThreadWrite(void* param)
{
    srand(GetTickCount());
    while (true)
    {
        Lock a(&mx);
        //WaitForSingleObject(hMutex, INFINITE);
        if (g_vec.size() > 0)
        {
            if (rand() % 100 > 50)
            {
                g_vec.push_back(rand() % 10000);
            }
            else
            {
                g_vec.erase(g_vec.begin());
            }
        }
        else
        {
            g_vec.push_back(rand() % 10000);
        }
        //ReleaseMutex(hMutex);
        Sleep(10);
    }
}

void unlock(mutex* pm)
{
    pm->unlock();
}

同步顺利时,显示的都是正常的值,不顺利时,显示的是未初始化的值

猜你喜欢

转载自blog.csdn.net/baidu_25539425/article/details/79946814