************************************************
时间:2013年10月18日
作者:常保龙
地点:核所C105
************************************************
STL容器的线程安全性:
1、多个读取者是安全的。多线程可能同时读取一个容器的内容,这将正确的执行。当然,在读取时不能有任何写入者操作这个容器;
2、对不同容器的多个写入者是安全的。多线程可以同时写不同的容器。
举例说明:
vector<int> v;
...
getMutexFor(v);
vector<int>::iterator first5(find(v.begin(), v.end(), 5));
if (first5 != v.end()) { // 这里现在安全了
*first5 = 0; // 这里也是
}
releaseMutexFor(v);
这种线程安全的表达方式,并不是完全安全的。如果在getMutexFor(v)和releaseMutexFor(v)之间程序抛出异常,互斥量将不会被释放;如果忘记
releaseMutexFor(v);这句代码,互斥量也不会被释放。所以这种手工调用互斥锁的方法,降低了程序的稳健性。
另一种方法是基于Lock类的方法实现的。
template<typename Container> // 获取和释放容器的互斥量
class Lock { // 的类的模板核心;
public: // 忽略了很多细节
Lock(const Containers container)
: c(container)
{
getMutexFor(c); // 在构造函数获取互斥量
}
~Lock()
{
releaseMutexFor(c); // 在析构函数里释放它
}
private:
const Container& c;
};
vector<int> v;
...
{ // 建立新块;
Lock<vector<int> > lock(v); // 获取互斥量
vector<int>::iterator first5(find(v.begin(), v.end(), 5));
if (first5 != v.end()) {
*first5 = 0;
}
}
C++保证如果抛出了异常,局部对象就会被销毁,所以即使当我们正在使用Lock对象时有异常抛出,Lock也将释放它的互斥量。