我应该是否同步双端队列

时间:2013-08-15 12:18:05

标签: c++ c multithreading deque

我在 C ++ 应用程序中有一个deque指针。我知道有两个线程来访问它。

Thread1 将从后面添加指针, Thread2 将处理并从前面删除指针。

Thread2 会等到deque达到一定金额,说出10个项目,然后开始处理它。它一次只能循环和处理10个项目。与此同时, Thread1 仍可能继续在双端队列中添加新项目。

我认为没有同步 deque会很好,因为 Thread1 Thread2 正在访问{{的不同部分1}}。它是deque而不是deque。因此,不会重新分配vector的现有内存。

我是对的吗?如果没有,为什么(我想知道我错过了什么)?

修改

我知道总是要同步它不会有什么坏处。但它可能会损害性能或不必要。我希望它尽可能快地运行。

2 个答案:

答案 0 :(得分:4)

deque必须跟踪它有多少元素以及这些元素的位置。添加元素会更改存储的数据,删除元素也是如此。在没有同步的情况下从两个线程更改数据是数据竞争,并产生未定义的行为。

简而言之,必须同步这些操作。

答案 1 :(得分:2)

一般情况下,不能假定标准库容器是线程安全的,除非你所做的就是从中读取它们。

如果您在deque实施后查看封面,您将发现类似的内容:

template <typename T>
class deque {
public:

private:
    static size_t const BufferCapacity = /**/;

    size_t _nb_available_buffer;
    size_t _first_occupied_buffer;
    size_t _last_occupied_buffer;

    size_t _size_first_buffer;
    size_t _size_last_buffer;

    T** _buffers; // heap allocated array of
                  // heap allocated arrays of fixed capacity
}; // class deque

你看到了问题吗? _buffers,至少可以通过enqueue和dequeue操作同时访问(特别是当数组变得太小而需要在更大的数组中复制时)。


那么,替代方案是什么?您正在寻找的是并发队列。有一些实现,除非它被证明是一个瓶颈,否则你可能不会过分担心它们是否无锁。一个例子是TTB concurrent_queue

我建议不要创建你自己的无锁队列,即使你听到了它的全部时尚,因为我所看到的所有首次实现都有(有时是微妙的)竞争条件。