2017-05-03 17 views
0

notify_all()メソッドを使用する例が必要です。私はそれがどのように動作するのか理解できないからです。std :: condition_variable :: notify_all() - 例が必要

すべての待機しているスレッドは、そのようなコードで始まる:スレッドがミューテックスを取得する必要が待っている、非常に冒頭で

std::unique_lock<std::mutex> lock(mutex); 
condition_variable.wait(lock, [](){return SOMETHING;}); 

。したがって、待機中のスレッドが複数ある場合は、それらの残りの部分がミューテックスをロックするのを待ちます。したがって、待機中のスレッドがmutexをロックしていて、wait()メソッドをまったく実行しない場合、notify_all()を使用する目的は何ですか?これらのスレッドは、同時にではなく1つずつ起動します。

+1

私は偉大な参照/サンプルサイトへご案内しましょう:のhttp:/ /en.cppreference.com/w/cpp/thread/condition_variable – NathanOliver

+0

私の問題は解決しません。ごめんなさい。 –

答えて

2

mutexは、condition_variableの内部状態を保護します。 condition_variablewaitを呼び出すと、ミューテックスのロックが解除されます。待機中にスレッドはmutexを所有しません。

waitが完了すると、waitの呼び出しが戻る前に、ミューテックスが再び(アトミックに)取得されます。

スレッドは、ミューテックスと競合していないため、条件自体に競合しています。

あなたが望むなら待ってすぐにロックを解除することは自由です。たとえば、ある条件で複数のスレッドを同期させたい場合は、これを行う方法です。この機能を使用してセマフォを実装することもできます。

例:

このコードはnotify_all()が行くこと10注意のバッチで物事を処理unlock()後:

#include <condition_variable> 
#include <mutex> 
#include <iostream> 
#include <string> 
#include <thread> 
#include <chrono> 
#include <vector> 

void emit(std::string const& s) 
{ 
    static std::mutex m; 
    auto lock = std::unique_lock<std::mutex>(m); 
    std::cout << s << std::endl; 
} 

std::mutex m; 
std::condition_variable cv; 
int running_count = 0; 

void do_something(int i) 
{ 
    using namespace std::literals; 

    auto lock = std::unique_lock<std::mutex>(m); 
    // mutex is now locked 

    cv.wait(lock, // until the cv is notified, the mutex is unlocked 
      [] 
      { 
       // mutex has been locked here 
       return running_count < 10; 
       // if this returns false, mutex will be unlocked again, but code waits inside wait() for a notify() 
      }); 
    // mutex is locked here 
    ++running_count; 
    lock.unlock(); 
    // we are doing work after unlocking the mutex so others can also 
    // work when notified 
    emit("running " + std::to_string(i)); 
    std::this_thread::sleep_for(500ms); 
    // manipulating the condition, we must lock 
    lock.lock(); 
    --running_count; 
    lock.unlock(); 
    // notify once we have unlocked - this is important to avoid a pessimisation. 
    cv.notify_all(); 
} 

int main() 
{ 
    std::vector<std::thread> ts; 
    for (int i = 0 ; i < 200 ; ++i) 
    { 
     ts.emplace_back([i] { do_something(i); }); 
    } 

    for (auto& t : ts) { 
     if (t.joinable()) t.join(); 
    } 

} 
+0

wait()メソッドがmutexのロックを解除するということですか? –

+0

@AkasataAkasata waitは同時にmutexのロックを解除し、条件変数に待機状態を入力します。条件変数が通知されると、すべてのウェイターが条件をテストするためにロックを再取得します。私はコードに注釈をつけるでしょう。 –

+0

ロックを順番に再取得する場合、notify_all()も順番にロックを解除しますか? –

関連する問題