2012-10-09 19 views
17

私はJavaコードをC++に移植する過程にあり、ある特定のセクションではBlockingQueueを使用して、多くのプロデューサから単一のコンシューマにメッセージを渡しています。C++ JavaのBlockingQueueに相当する

Java BlockingQueueに精通していない場合は、キューからput()およびtake()するスレッドセーフメソッドを公開するハード容量のキューに過ぎません。キューが満杯の場合はブロックをput()し、キューが空の場合はブロックをtake()します。また、これらのメソッドのタイムアウト対応バージョンも提供されています。

タイムアウトは私のユースケースに関連しているため、それらを提供する推奨が理想的です。もしそうでなければ、私は自分自身をコード化することができます。

私はグーグルでブーストライブラリをすばやく閲覧しましたが、このようなものは見つかりませんでした。多分私はここで目が見えません...しかし、誰も良い推薦を知っていますか?

ありがとうございます!

+0

配列を持つハンドメイドクラス(pop_front push_backを簡単にするために配列の代わりにdequeを使うかもしれない)とmutex? – NoSenseEtAl

+0

本当に必要なハード容量ですか? –

+1

私の場合、はい。生産者が消費者を上回る可能性は非常に高いですし、生産者側のスレッドをブロックする必要があります。そうでなければ、入力が拒否されます。 – Ben

答えて

32

サイズが固定されておらず、それがタイムアウトをサポートしていませんが、ここで私はC++ 2011の構築物を用いて最近投稿されたキューの簡単な実装です:

#include <mutex> 
#include <condition_variable> 
#include <deque> 

template <typename T> 
class queue 
{ 
private: 
    std::mutex    d_mutex; 
    std::condition_variable d_condition; 
    std::deque<T>   d_queue; 
public: 
    void push(T const& value) { 
     { 
      std::unique_lock<std::mutex> lock(this->d_mutex); 
      d_queue.push_front(value); 
     } 
     this->d_condition.notify_one(); 
    } 
    T pop() { 
     std::unique_lock<std::mutex> lock(this->d_mutex); 
     this->d_condition.wait(lock, [=]{ return !this->d_queue.empty(); }); 
     T rc(std::move(this->d_queue.back())); 
     this->d_queue.pop_back(); 
     return rc; 
    } 
}; 

拡張するのは簡単であるべきと使用ポップするためのタイムアウト待ち。私がそれをしていない主な理由は、私が今まで考えてきたインターフェースの選択に満足していないということです。

+0

は、プッシュの必要がありますか?私はmutexのロックを解除しようとしていると思います...しかし、notify_oneの前提条件はわかりません。 – NoSenseEtAl

+8

'push()'のスコープは必要ありませんが、それがなければ、ロックがまだ保持されている間に条件変数が通知されます。シグナリングの前にロックを解除すると、ロックがすぐに利用可能になります。 –

+0

この例では、 'timed wait for popping'のためのある程度の可能性がありますか? – javapowered