STL线程安全

在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;
}															// 关闭块, 自动释放互斥量
上一篇:数据结构之栈


下一篇:STL string容器用法