什么时候 deq​​ueue 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++ 也不保证关于不同整数的原子性。除非保证是线程安全的,否则永远不要假设某些东西是线程安全的。