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();
}

同步順利時,顯示的都是正常的值,不順利時,顯示的是未初始化的值

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章