1

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

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

Thread2将等到达到一定数量,即 10 个项目,然后开始处理它deque它一次只会循环和处理 10 个项目。与此同时,线程1可能仍会继续向双端队列添加新项目。

我认为不同步就可以了,deque因为Thread1Thread2正在访问deque. 它deque不是vector。所以不存在现有内存的情况container不会重新分配现有内存的情况。

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

编辑:

我知道总是同步它不会有什么坏处。但这可能会损害性能或没有必要。如果可能的话,我只是希望它运行得更快、更正确。

4

2 回答 2

4

双端队列必须跟踪它有多少元素以及这些元素在哪里。添加元素会更改存储的数据,就像删除元素一样。在没有同步的情况下从两个线程更改该数据是一种数据竞争,并且会产生未定义的行为。

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

于 2013-08-15T12:22:17.967 回答
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,至少,可以通过入队和出队操作同时访问(特别是当数组变得太小并且需要复制到更大的数组中时)。


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

我建议不要创建你自己的无锁队列,即使你听说这都是时尚,因为我见过的所有第一个实现都有(有时是微妙的)竞争条件。

于 2013-08-15T12:35:42.280 回答