1

C++アプリケーションdeque内に with ポインターがあります。私はそれにアクセスするための2つのスレッドがあることを知っています。

Thread1は後方からポインターを追加し、Thread2は前方からポインターを処理して削除します。

Thread2は、deque10 アイテムと言う一定の量に達するまで待ってから、処理を開始します。一度に 10 個のアイテムのみをループして処理します。その間、Thread1は新しい項目を両端キューに追加し続ける可能性があります。

Thread1Thread2は の異なる部分にアクセスしているため、を同期しなくても問題ないと思います。そうではありません。そのため、 の既存のメモリが再割り当てされることはありません。dequedequedequevectorcontainer

私は正しいですか?そうでない場合、なぜですか (何が欠けているのか知りたいのですが)?

編集:

常に同期しても問題ないことはわかっています。ただし、パフォーマンスが低下するか、必要ない場合があります。可能であれば、より速く正確に実行したいだけです。

4

2 に答える 2

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 に答える