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

猜你喜欢

转载自www.cnblogs.com/joeylee97/p/8971058.html