0

std::list を使用して文字列を保持し、1 つのスレッドがリストに書き込み、他のスレッドがそれから読み取ります (最初のものを取得してリストから消去します)。コードは次のとおりです。

std::list<string> list_;

boost::condition_variable cond;
boost::shared_mutex mtx;

int get_size() {
    boost::shared_lock<boost::shared_mutex> lock(mtx);
    return list_.size();
}

// add a string to the list
// invoked by only one thread
void add_one(const string& p) {
    {
        boost::upgrade_lock<boost::shared_mutex> lock(mtx);
        boost::upgrade_to_unique_lock<boost::shared_mutex> uniquelock(lock);

        list_.push_back(p);
    }
    cond.notify_one();
}

// get the first string and remove it from the list
// invoked by many threads
string pick_one() {
    string ret;
    {
        boost::upgrade_lock<boost::shared_mutex> lock(mtx);
        boost::upgrade_to_unique_lock<boost::shared_mutex> uniquelock(lock);

        if(!list_.size()) { // if empty, wait for notify
            cond.wait(uniquelock, [&]{ return list_.size() > 0; }); // compile error
        } 
        ret = list_.front();
        list_.pop_front();
    }
    return ret;
}

行にコンパイルエラーがありますcond.wait(uniquelock, ...

condition_variable で読み取り/書き込みロックを使用する正しい方法は何ですか?

4

1 に答える 1

0

これを行うことはできません。これupgrade_to_unique_lockは、ロックの存続期間中の排他的アクセスを取得するための RAII ヘルパーです。こちらのドキュメントを参照してください。

boost::upgrade_to_unique_lock を使用すると、boost::upgrade_lock を排他的所有権に一時的にアップグレードできます。boost::upgrade_lock のインスタンスへの参照を使用して構築された場合、そのインスタンスがロック可能なオブジェクトのアップグレード所有権を持っている場合、その所有権は排他的所有権にアップグレードされます。boost::upgrade_to_unique_lock インスタンスが破棄されると、Lockable の所有権がダウングレードされ、所有権がアップグレードされます。

shared_mutexBoost 条件変数を使用する場合は、ここで説明されているように使用する必要がありboost::condition_variable_anyます。2 つの条件変数の違い (ではなくを参照していますが) については、ここで説明します。stdBoost

于 2016-05-23T13:12:15.317 に答える