什么时候 dequeue size 调用不是线程安全的?
When is dequeue size call not thread safe?
一般来说,在重新分配发生时,对标准容器的操作是 not thread safe (mostly). The size
call on a std::vector
, for example, may fail。
自从 dequeue
does not reallocate or move the elements like a standard vector does, are there still conditions when calling size
on a dequeue can be unsafe? The most likely scenario seems to be when adding/removing elements in a different thread as the size
call is being made, but since accessing an integer is mostly safe 以来,我很难想象如何从单独的线程调用 size
会有问题。
比如像这样
std::deque<int> dq;
dq.push_back(1);
// thread0
void printElementIfExist() {
if (dq.size() > 0) {
std::cout << dq[0] << std::endl;
}
}
// thread1
void removeElementFromDeque() {
if (dq.size() > 0) {
dq.pop_back();
}
}
竞争条件可能允许访问已被释放的 dq[0]
。
回到 size()
调用本身。在某些架构中,读取操作不是原子操作。
曾经。因为在任何标准中都不需要如此。
这里的GCC实现https://github.com/gcc-mirror/gcc/blob/master/libstdc%2B%2B-v3/include/bits/stl_deque.h是减法的结果:
// [23.2.1.2] capacity
/** Returns the number of elements in the %deque. */
size_type
size() const _GLIBCXX_NOEXCEPT
{ return this->_M_impl._M_finish - this->_M_impl._M_start; }
即使 size 存储在 size_t
甚至 uint8_t
中,并且 size()
是 return 这个变量的内联函数,C++ 也不保证关于不同整数的原子性。除非保证是线程安全的,否则永远不要假设某些东西是线程安全的。
一般来说,在重新分配发生时,对标准容器的操作是 not thread safe (mostly). The size
call on a std::vector
, for example, may fail。
自从 dequeue
does not reallocate or move the elements like a standard vector does, are there still conditions when calling size
on a dequeue can be unsafe? The most likely scenario seems to be when adding/removing elements in a different thread as the size
call is being made, but since accessing an integer is mostly safe 以来,我很难想象如何从单独的线程调用 size
会有问题。
比如像这样
std::deque<int> dq;
dq.push_back(1);
// thread0
void printElementIfExist() {
if (dq.size() > 0) {
std::cout << dq[0] << std::endl;
}
}
// thread1
void removeElementFromDeque() {
if (dq.size() > 0) {
dq.pop_back();
}
}
竞争条件可能允许访问已被释放的 dq[0]
。
回到 size()
调用本身。在某些架构中,读取操作不是原子操作。
曾经。因为在任何标准中都不需要如此。
这里的GCC实现https://github.com/gcc-mirror/gcc/blob/master/libstdc%2B%2B-v3/include/bits/stl_deque.h是减法的结果:
// [23.2.1.2] capacity
/** Returns the number of elements in the %deque. */
size_type
size() const _GLIBCXX_NOEXCEPT
{ return this->_M_impl._M_finish - this->_M_impl._M_start; }
即使 size 存储在 size_t
甚至 uint8_t
中,并且 size()
是 return 这个变量的内联函数,C++ 也不保证关于不同整数的原子性。除非保证是线程安全的,否则永远不要假设某些东西是线程安全的。