美文网首页
Effective STL 第12条

Effective STL 第12条

作者: 懒生活 | 来源:发表于2022-09-10 22:55 被阅读0次

    容器的线程安全性

    不能对容器的线程安全性抱太大的期望

    对于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;
    }
    

    相关文章

      网友评论

          本文标题:Effective STL 第12条

          本文链接:https://www.haomeiwen.com/subject/zmnznrtx.html