c++ 高效並發編程


高效並發編程

並發編程的基本模型包括,通過消息機制來管理運行順序的message passing, 通過互斥保護共享的shared memory。

線程同步的基本原則

  1. 最低限度共享變量,考慮使用immutable對象
  2. 盡量減小鎖粒度
  3. 互斥器和條件變量足以完成絕大多數任務,盡量使用高層的封裝
  4. 避繁就簡,讀寫鎖 信號量 可重入鎖 ,慎用。

關於死鎖

  1. RAII 控制鎖區間
  2. 注意鎖的獲取順序

Copy On Write 減小鎖粒度

只讀的情況下用shared_ptr 輕量級共享數據
在發生修改的情況下,對發生次數較小的情況做數據拷貝,比如說我們的數據每秒鍾被讀取一百次,平均每十秒添加一次數據,那么就針對添加數據的情況做Copy on write,添加數據時如果數據被使用,就copy一份!(由於使用數據線程保存了一份shared_ptr,所以沒有問題)
我們來看一個例子

class Foo
{
 public:
  void doit() const;
};

typedef std::vector<Foo> FooList;
typedef boost::shared_ptr<FooList> FooListPtr;
FooListPtr g_foos;
MutexLock mutex;

void post(const Foo& f)
{
  printf("post\n");
  MutexLockGuard lock(mutex);
  if (!g_foos.unique())//有其他線程在讀,重新拷貝一份
  {
    g_foos.reset(new FooList(*g_foos));
    printf("copy the whole list\n");
  }
  assert(g_foos.unique());
  g_foos->push_back(f);
}

void traverse()
{
  FooListPtr foos;
  {
    MutexLockGuard lock(mutex);
    foos = g_foos;
    assert(!g_foos.unique());
  }

  // assert(!foos.unique()); this may not hold

  for (std::vector<Foo>::const_iterator it = foos->begin();
      it != foos->end(); ++it)
  {
    it->doit();
  }
}

void Foo::doit() const
{
  Foo f;
  post(f);
}

int main()
{
  g_foos.reset(new FooList);
  Foo f;
  post(f);
  traverse();
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM