C ++ 11マルチスレッドの記録6:条件変数(条件変数)

https://www.youtube.com/watch?v=13dFggo4t_Iビデオアドレス

例1

。シナリオを検討:両端キューの両端キューから一つのグローバルキュー両端キュー、スレッドAプッシュデータ(書き込み)、抽出されたスレッドBデータ(読み出し)が存在し
たDequeオブジェクトはミューテックスと、このリソースへのアクセス制御を行うことで、コードは以下の通りであります:

std::deque<int> q;
std::mutex mu;

void func1() {
    int ct = 10;
    while (ct > 0) {
        std::unique_lock<std::mutex> lock(mu);
        q.push_front(ct);
        lock.unlock();
        std::this_thread::sleep_for(chrono::seconds(1));
        ct --;
    }
}

void func2() {
    int data = 0;
    while (data != 1 ) {
        std::unique_lock<std::mutex> lock(mu);
        if (!q.empty()) {
            data = q.back();
            q.pop_back();
            lock.unlock();
            ...
        } else {
            lock.unlock();
        }
    }
}

int main() {
    std::thread t1(func1);
    std::thread t2(func2);
    t1.join();
    t2.join();
    return 0; 
}

T1スレッド、サイクルは、「生産者」のようにデータのキュー、各睡眠一秒;.にプッシュされる
キューから連続的に読み出されたデータは(データがあるかどうか最初に決定する)、スレッドT2;「消費者として。 "

問題があります:スレッドT2、裁判官は、最初両端キューが空になるでしょう。空の場合は、ロック解除を実行し、その後すぐに(状態が真であるかどうかを判断するために頻繁に繰り返される)ビジーウェイトで、その結果、次のサイクルを入力します。

次のように一つの解決策は次のとおりです。

void func2() {
    ...
    } else {
        lock.unlock();
        std::this_thread::sleep_for(chrono::seconds(1));
    }
}

発見キューで寝の時間はあなたがある程度問題を解決することができ、空です。
しかし、時間変数は値が良好でないかを判断するために設定され、セットがビジーウェイトに戻る可能性があり、小さすぎる、大きすぎる設定し、それはデータへのタイムリーなアクセスにつながることはありません

条件変数

それはとても消費者は「盲目的に待機」していないことを、変数の条件でこの問題との良好な取引することができ

std::deque<int> q;
std::mutex mu;
std::condition_variable cond;

void func1() {
    int ct = 10;
    while (ct > 0) {
        std::unique_lock<std::mutex> lock(mu);
        q.push_front(ct);
        lock.unlock();
        cond.notify_one(); // wake up one waiting thread
        // cond.notify_all(); // wake up all waiting threads
        std::this_thread::sleep_for(chrono::seconds(1));
        ct --;
    }
}

void func2() {
    int data = 0;
    while (data != 1 ) {
        std::unique_lock<std::mutex> lock(mu);
        cond.wait(lock, [](){ return !q.empty(); });
        data = q.back();
        q.pop_back();
        lock.unlock();
    }
}

呼ばれる銀行のカウンターに類似;データは両端キューの実行notify_oneに押し込まれた後、プロデューサーのスレッド、()には、1つのスレッドを覚ますことができます
睡眠を待って、消費者スレッド、ちょうどcond.wait(ロック、...)彼らは「数と呼ばれる」されるまで、スリープ待ち、(ダウン実行され、それがfalseを返した場合、それが目覚めているとき、2番目のパラメータはスリープしていきます本当です)CPU時間を取らない
注意をその中cond.wait(ロック)最初の睡眠の占領前にロックを解除します。それが目覚めた時に最初にmutexを取り上げます。

概要

condition_variableは、大雑把に言えば、それはに類似していてもよい「ウェイクアップサービス。」

おすすめ

転載: www.cnblogs.com/ChenLambda/p/11832656.html