2

ブロッキングキューを実装しようとしています。主な部分は次のとおりです(これは一種の教育タスクです)

template <typename T>
class Blocking_queue
{
public:
    std::queue<T> _queue;
    boost::mutex _mutex;
    boost::condition_variable _cvar;

    void Put(T& object);
    T Get();
    void Disable()
};


template<typename T>
void Blocking_queue::Put(T& object)
{
    boost::mutex::scoped_lock lock(_mutex);
    _queue.push(T);
    lock.unlock();
     _cvar.notify_one();
}

template<typename T>
T Blocking_queue::Get()
{
    boost::mutex::scoped_lock lock(_mutex);

    while(_queue.empty())
    {
        _cvar.wait(_mutex);
    }

    T last_el = _queue.front();
    _queue.pop();
    return last_el;
}

template<typename T>
void Blocking_queue::Disable()
{

}

そして、(タスクで記述されているように)すべての待機中のスレッドを「解放」する関数Disable()を実装する必要があります。問題は、この用語での「リリース」が何を意味するのか、そしてどのような方法を適用すべきかを完全に理解していないことです。だから私の考えは次のとおりです:Disable()が呼び出されたら、この場所(ループ内)で現在のスレッドのメソッドを呼び出す必要があります

    while(_queue.empty())
    {
        //here
        _cvar.wait(_mutex);
    }

これは現在のスレッドを解放します、私は正しいですか?ありがとう。

4

1 に答える 1

1

「待機中のスレッドをすべて解放する」というのは、ほとんど役に立たない操作です。この操作で何をしたいですか?

便利なのは、キューをシャットダウンすることです。これにより、キューで待機しているすべてのスレッドのブロックが解除され、Get()を呼び出すすべてのスレッドがすぐに戻ります。このような動作を実装するには、キューにシャットダウンフラグを追加し、「空でないかシャットダウンしない」まで待ちます。

template<typename T>
void Blocking_queue::Disable()
{
    boost::mutex::scoped_lock lock(_mutex);
    _shutdown = true;

    _cvar.notify_all()
}

データがないことを示すために、Get()の呼び出し元に、追加のブール値を含むペアを返すか、特別な例外をスローすることができます。すべてのタイプTにnull値があるわけではないため、nullを返す方法はありません。

template<typename T>
std::pair< bool, T > Blocking_queue::Get()
{
    boost::mutex::scoped_lock lock(_mutex);

    while  (_queue.empty() && !_shutdown )
        _cvar.wait(_mutex);

    if ( _shutdown )
        return std::make_pair( false, T() );

    T last_el = _queue.front();
    _queue.pop();
    return std::make_pair( true, last_el );
}
于 2012-09-21T10:04:56.867 に答える