在STL容器里对多线程支持的黄金规则已经由SGI定义
1.多个读者是安全的。多线程可能同时读取一个容器的内容,这将正确的执行,当然,在读取时不能有任何写入者操作这个容器
2.对不同容器的多个写入者是安全的,。多线程可以同时写不同的容器
一个库可能试图以下列方式实现线程安全的容器
1.每次调用容器的成员函数期间都要锁定该容器
2.每个容器返回的迭代器的生存期内都要锁定该容器
3.每个容器调用算法执行期间锁定该容器
上面举例的锁定方法不能防止下面代码的问题
vector<int> v;
vector<int>:: iterator first5(find(v.begin(), v.end(), 5));
if(*first5 != v.end())
*first5 = 0;
例如, 另一个线程在行 1 完成之后立即修改 v 中的数据, 导致行2, 行3 不能正常运行
为了代码成为线程安全的,V 必须从行1 到 行3 保持锁定, 手工同步控制
vector<int> v;
...
getMutexFor(v);
...
releaseMutexFor(v);
一个更面向对象的解决方案是创建一个Lock 类, 在构造函数里获得互斥量并在析构函数里释放它,这样使 getMutexFor 和 releaseMutexFor 的调用不匹配的机会减到最小:
template<typename Container> // 获取释放容器的互斥量的类的模板核心
class Lock
{
public:
Lock(const Containers container) : c(container)
{
getMutexFor(c);
}
~Lock() { releaseMuterFor(c); }
private:
const Container &c;
}
使用 Lock 类来获取互斥量
list<int> l;
...
{ // 建立一个块
Lock<list<int>> lock(v); // 获取互斥量
list<int>::iterator lfind5(find(list.begin(), list.end(), 5));
if ( *lfind5 != v.end() )
*lfind5 = 0;
} // 关闭块, 自动释放互斥量