gpt4 book ai didi

c++ - 使用索引安全方式迭代 STL 容器以避免使用锁?

转载 作者:行者123 更新时间:2023-11-30 02:56:35 27 4
gpt4 key购买 nike

想知道以下列方式迭代 STL 容器(如 vector )是否安全以避免锁定读/写,但仅允许任何“写入”线程进行 push_back() 操作。

for (size_t i = 0; i < vec.size(); i++)
{
const T& t = *vec[i];
// do something with t
}

我知道迭代器可能会因容器的更改而失效,但也许如果我们确保初始容器大小足以容纳任何 future 的添加,那么在不锁定读取或写入的情况下迭代元素也应该是安全的?

最佳答案

Wondering if it's safe to iterate over a STL container such as a vector in the following manner to avoid locking on reads/writes but allowing for push_back() operations only by any "writing" threads.

不要,这不是线程安全的。考虑一个试图读取值并转到当前缓冲区的线程。此时第二个线程正在增长缓冲区,在第一个线程获得指向缓冲区的指针之后,但在它实际读取值之前,第二个线程释放缓冲区的内容。第一个线程正在读取死对象,这是未定义的行为。

将问题限制在 reserve() vector (即避免缓冲区增长的问题)中,该方法仍然不是线程安全的。 push_back() 中的代码将执行类似以下操作:

template <...>
class vector {
T *begin,*end,*capacity; // common implementation uses 3 pointers

void push_back(T value) {
if (end == capacity) { /* grow vector and insert */ }
else {
new (end) T(value);
++end;
}
}
};

这里的问题是,如果没有同步机制,编译器可以重新排序指令,递增 end 并将其存储到内存中,然后在缓冲区元素上调用 T 的构造函数.如果发生重新排序,那么您的阅读器线程可能会看到 size() 的值,其中包括当前正在存储的值,但该值尚未在 vector 中。

关于c++ - 使用索引安全方式迭代 STL 容器以避免使用锁?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15370644/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com