首页 > 解决方案 > 这是一个线程安全的向量,如果是这样,为什么 std::vector 的某些方法需要锁定线程安全而其他方法不需要?

问题描述

作为线程的完全新手,我做了一些探索,以寻找线程安全的 std::vector 的实现。基于(大量)我的阅读,我想出了这个:

    # include <vector>

    template<class ContainedType>
    class ThreadSafeVector {
    public:
        ThreadSafeVector()
                : vec_(), mut_(), cond_() {}

        explicit ThreadSafeVector(std::vector<ContainedType> vec)
                : vec_(vec), mut_(), cond_() {};

        ThreadSafeVector(std::initializer_list<ContainedType> vec)
                : vec_(std::vector<ContainedType>(vec.begin(), vec.end())), mut_(), cond_() {};

        ~ThreadSafeVector() = default;

        void insert(ContainedType in, int index) {
            std::lock_guard<std::mutex> lock(mut_);
            vec_[index] = std::move(in);
            cond_.notify_one();
        }

        void push_back(ContainedType in) {
            std::lock_guard<std::mutex> lock(mut_);
            vec_.push_back(in);
            cond_.notify_one();
        }

        ContainedType &operator[](int index) {
            return vec_[index];
        }

        typename std::vector<ContainedType>::iterator begin() {
            return vec_.begin();
        }

        typename std::vector<ContainedType>::iterator end() {
            return vec_.end();
        }

        std::vector<ContainedType> toVector(){
            return vec_;
        }

    private:
        std::vector<ContainedType> vec_;
        std::mutex mut_;
        std::condition_variable cond_;
    };

第一个问题,这是向量的线程安全实现吗?第二个问题,如果是,那么为什么需要调用push_back和调用,而不要调用?谢谢insertlock_guardcond_.notifyoperator[]begin()end()

标签: c++multithreadingvectorthread-safety

解决方案


不,这不是线程安全的。

线程1可以进入:

ContainedType &operator[](int index) 
    {
        return vec_[index];
    }

并且刚刚计算了引用ContainedType &并将其写入返回值。然后线程 2 进入:

void push_back(ContainedType in) {

并且向量无效,因此引用也无效。繁荣。


推荐阅读