容器的线程安全性
不能对容器的线程安全性抱太大的期望
对于stl容器,大部分容器只能保证
1)支持多线程同时读
2)支持多线程对不同的容器同时进行写
容器读写的线程安全性要靠用户自己保证.
vector<int> v;
vector<int>::iterator first5(find(v.begin(), v.end(),5));
if(first5!=v.end())
*first5 = 12;
对于上面这段代码,如果在找到并构建first5之后,如果有其它的线程对v进行了操作,如删除中间某个元素,直接会导致这个迭代器失效.此时线程的安全性就出现问题了.
为了保证线程安全,上面的代码要做如下的互斥
#include <mutex>
vector<int> v{ 1,3,4,5,56 };
std::mutex mutexForV;
int main()
{
mutexForV.lock();
vector<int>::iterator first5(std::find(v.begin(), v.end(), 5));
if(first5!=v.end())
*first5 = 15;
mutexForV.unlock();
}
更好的手动互斥手段
上面的互斥手段依赖于lock和unlock, 如果在lock之后,发生异常, 那么永远不会执行unlock. 这可能会导致死锁. 使用lock_gard优化上面的代码. 因为c++保证,在发生异常的时候,创建的局部变量都会被析构.这样mutexForV_gard不管什么时候发生异常,离开作用域后肯定会被析构掉,析构的时候,可能会释放锁. 不光是保证了异常安全,而且也避免了编码时忘记unlock的风险.
vector<int> v{ 1,3,4,5,56 };
std::mutex mutexForV;
int main()
{
std::lock_guard<std::mutex> mutexForV_gard(mutexForV);
vector<int>::iterator first5(std::find(v.begin(), v.end(), 5));
if(first5!=v.end())
*first5 = 15;
}
网友评论