2017-05-03 64 views
0

我需要一个使用notify_all()方法的例子。因为我不明白它应该如何工作。std :: condition_variable :: notify_all() - 我需要一个例子

每一个等待的线程开始的代码这样的:

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

开始的时候,等待线程需要获取互斥锁。所以如果有多个等待线程,其余的将等待锁定一个互斥锁。那么,如果等待的线程停留在锁定互斥量并且根本不执行方法wait(),那么使用notify_all()的目的是什么?这些线程将逐个唤醒,而不是同时唤醒。

+1

让我引导您有很大的参考/例如站点:http:/ /en.cppreference.com/w/cpp/thread/condition_variable – NathanOliver

+0

它不能解决我的问题。抱歉。 –

回答

2

互斥量守护着condition_variable的内部状态。在condition_variable上调用wait会导致互斥锁被解锁。所以在等待时,线程不拥有互斥量。

wait完成时,在调用wait返回之前,互斥量再次(原子地)获取。

线程没有在互斥体上竞争,它们正在竞争条件本身。

如果您愿意,只要您从等待中返回,您就可以自由解锁。例如,如果您希望允许多个线程在某种情况下进行同步,则您将如何执行此操作。您也可以使用此功能来实现信号量。

例如:

此代码处理的事情在10注批次是notify_all()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()方法解锁互斥锁吗? –

+0

@AkasataAkasata等待同时解锁互斥锁并在条件变量上进入等待状态。当条件变量被通知时,所有服务员重新获得锁以便测试条件。我会注释代码。 –

+0

因此,如果他们正在重新获取锁定,notify_all()也会依次唤醒它们,对吧? –

相关问题