1. 程式人生 > >shared_ptr實現copy-on-write

shared_ptr實現copy-on-write

最近再看陳碩的《Linux多執行緒服務端程式設計使用muduoC++網路庫》,2.8節看到這個內容:使用shared_ptr實現copy-on-write的手法降低鎖競爭。

目的: 利用普通mutex替換讀寫鎖

  • shared_ptr是引用技術型智慧指標,當只有一個觀察者時,引用計數為1。
  • 對於write端,如果發現引用計數為1(即當前只有自己持有智慧指標),那可以加鎖後安全的修改。如果大於1,則需要拷貝當前資料構再修改。程式碼實現就是拷貝構造一個新的FooList,然後在這個新的Foolist中寫。
  • 對於read端,在讀之前加鎖後將引用計數加1,就可以安全的讀取。將引用計數加1,保證了寫端不會去併發寫。
void read()
{
    FoolPtr foos; //智慧指標物件
    {
    MutexLockGuard lock(mutex_);
    foos = g_foos; //引用計數加1
    }
    for( .... )
    //read ...
}

void write(const foo& f)
{
    MutexLockGuard lock(mutex_);
    if(!g_foos.unique()) //如果此時引用計數不為1,則需要拷貝物件
    {
        g_foos.reset(new FooList(*g_foos));
    }
    g_foos->push(f); 
}

g_foos.reset 當g_foos僅僅只是將引用計數減1,只有當引用計數為1的時候,才會析構其管理的物件。

效能分析:

  • read時:構造一個智慧指標物件,引用計數加1,但是大大減小了鎖的粒度
  • write時:當發現引用計數大於1時,即有別的執行緒正在讀,此時需要拷貝構造一個新的容器物件出來,然後在新的物件裡write。當別的執行緒讀取完畢時,隨著智慧指標物件析構,引用計數為0,原有容器物件也就析構了