Effecitve stl 第一章 第12条
来源:互联网 发布:美国国际数据集团 编辑:程序博客网 时间:2024/06/05 16:23
第12条:切勿对STL容器的线程安全性有 不切实际的依赖。
对一个STL实现最多只能期望:
1 多个线程读是安全的。多个线程可以同时读一个容器的内容,而且保证是正确的。自然地,在读的过程中,不能对容器有任何写入操作。
2 多个线程对不同的容器做写入操作时安全的。多个线程可以同时对不同的容器做写入操作。
这是所能期望的,而不是所能依赖的,有些实现提供了这些保证,有些则没有。
现在考虑下面的代码: 在一个vector<int>中查找值为5的第一个元素,如果找到了,就将它设为0
vector<int> v;
....
vector<int>::iterator first5(find(v.begin(), v.end(), 5)); //第1行
if (first5 != v.end()) //第2行
*first5 = 0; //第3行
以上可能发出的线程不安全有
如果在第1行刚刚完成后,另一个不同的线程会更改v中的数据,如果发生了,则第2行对first5和v.end是否相等的检查将会变得没有意义,以为v的值与第一行结束时的是不同的。
事实上,这一检查可能导致不确定的行为,因为另外一个线程可能会夹在第1行和第2行中间,使first5变得无效,
或者这第二个线程可能会执行一个插入操作使得vector重新分配他的内存(这将会使vector得所有迭代器变得无效)。
同样的,对*first5的赋值也是不安全的,因为一个线程可能在第2行和第3行之间执行,该线程可能会使first5无效,例如可能会删除它所执行的元素(或者至少是曾经指向过的元素)。
这时不能指望任何STL实现解决这个线程问题,这种情况下,应该手工做同步控制,例如下面:
方案1:
vector<int> v;
....
getMutexFor(v);
vector<int>::iterator first5(find(v.begin(), v.end(), 5)); //第1行
if (first5 != v.end()) //第2行
*first5 = 0; //第3行
releaseMutexFor(v);
方案2:
使用一个Lock类,面向对象的方法,在构造函数中获得一个互斥体,在析构函数中释放它,从而尽可能得减少getMutexFor调用而没有相对应的releaseMutexFor调用的可能性。
template <typename Container> //一个为容器获取和释放互斥体的模板
class Lock
{
public:
Lock(const Container& 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)); //第1行
if (first5 != v.end()) //第2行
*first5 = 0; //第3行
} //代码块结束,自动释放互斥体如果没有创建代码块,也仍然会释放,只不过是当控制到达包含lock的代码块末尾时。
基于Lock的方案在有异常时也是强壮的, c++ 保证,如果有异常抛出,局部对象也会被析构,即即使当我们在使用Lock对象时又异常抛出,lock仍会释放它所有的互斥体。
- Effecitve stl 第一章 第12条
- Effective stl 第一章 第7、8条
- Effective STL 第一章 第9条
- Effective stl 第一章 第10条
- Effective stl 第6条
- effective stl 第15条
- Effective STL 第12条:切勿对STL容器的线程安全性有不切实际的依赖
- effective stl 第12条: 切勿对STL容器的线程安全性有不切实际的依赖
- Effective STL 第2、3、4条
- 第一章第12题
- Effective stl 第1章 容器 第5条
- Effective STL 第1条:慎重选择容器类型
- effective stl 第18条: 避免使用vector<bool>
- effective stl 第30条:确保目标区间足够大
- effective stl 第36条:理解copy_if的正确实现
- effective stl 第39条:确保判别式是“纯函数”
- effective stl 第47条:避免产生“直写型”的代码
- Effective stl 第一章 容器
- TO_CHAR(DATE,FORMAT)
- Android学习笔记 第七章
- Android音频系统之AudioFlinger(二)
- 转 从51到ARM——LPC1788学习笔记[最后更新:8月23日
- 华为 MUX VLAN
- Effecitve stl 第一章 第12条
- QTP 检查对象的存在的优化方法
- jsp之间的异步提交和返回数据。。
- Android音频系统之AudioFlinger(三)
- 每个程序员应该知道的12个API
- 强大的vim配置文件,让编程更随意
- Android音频系统之AudioFlinger(四)
- VxWorks常用函数速查
- visual assist alg+g不管用