线程间共享数据

本文是基于《C++并发编程》第三章的读书笔记

1.条件竞争(race condition)

并发中竞争条件的形成,取决于一个以上线程的相对执行顺序,每个线程都抢着完成自己的任务。大多数情况下,即使改变执行顺序,也是良性竞争,其结果可以接受。恶性条件竞争通常发生于完成对多于一个的数据块的修改时,例如,对两个连接指针的修改。因为操作要访问两个独立的数据块,独立的指令将会对数据块将进行修改,并且其中一个线程可能正在进行时,另一个线程就对数据块进行了访问。
保护共享数据结构的最基本的方式,是使用C++标准库提供的互斥量(mutex)。

2.C++11的互斥器

上一篇实现了一个互斥器,看一下C++11提供的互斥器的用法。

#include <mutex>

std::mutex one_mutex;

{
    std::lock_guard<std::mutex> guard(one_mutex);
    ... ...
}

3. 死锁:解决方案

避免嵌套锁

第一个建议往往是最简单的:一个线程已获得一个锁时,再别去获取第二个(don’t acquire a lock if you already hold one)。当你需要获取多个锁,使用一个std::lock来做这件事(对获取锁的操作上锁),避免产生死锁。

避免在持有锁时调用用户提供的代码

第二个建议是次简单的:因为代码是用户提供的,你没有办法确定用户要做什么;用户程序可能做任何事情,包括获取锁。

使用固定顺序获取锁

当硬性条件要求你获取两个以上(包括两个)的锁,并且不能使用std::lock单独操作来获取它们;那么最好在每个线程上,用固定的顺序获取它们获取它们(锁)。