这是线程安全向量吗?如果是,为什么 std::vector 的某些方法需要锁定线程安全而其他方法不需要?
Is this a thread safe vector, and if so why do some methods of std::vector require locking for thread safety while others do not?
作为线程的新手,我四处寻找线程安全的实现 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_;
};
第一个问题,这是 vector 的线程安全实现吗?第二个问题如果是,那么为什么 push_back
和 insert
需要调用 lock_guard
和 cond_.notify
而 operator[]
、begin()
和 end()
不要?谢谢
不,这不是线程安全的。
线程 1 可以进入:
ContainedType &operator[](int index)
{
return vec_[index];
}
并且刚刚计算了引用 ContainedType &
并且刚刚将其写入 return 值。然后线程 2 进入:
void push_back(ContainedType in) {
向量失效,因此引用也失效。轰.
作为线程的新手,我四处寻找线程安全的实现 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_;
};
第一个问题,这是 vector 的线程安全实现吗?第二个问题如果是,那么为什么 push_back
和 insert
需要调用 lock_guard
和 cond_.notify
而 operator[]
、begin()
和 end()
不要?谢谢
不,这不是线程安全的。
线程 1 可以进入:
ContainedType &operator[](int index)
{
return vec_[index];
}
并且刚刚计算了引用 ContainedType &
并且刚刚将其写入 return 值。然后线程 2 进入:
void push_back(ContainedType in) {
向量失效,因此引用也失效。轰.