设为首页 加入收藏

TOP

C++11并发编程-条件变量(condition_variable)详解(二)
2015-11-21 00:58:41 来源: 作者: 【 】 浏览:5
Tags:并发 编程 条件 变量 condition_variable 详解
::mutex, std::unique_lock #include // std::condition_variable, std::cv_status std::condition_variable cv; int value; void do_read_value() { std::cin >> value; cv.notify_one(); } int main () { std::cout << "Please, enter an integer (I'll be printing dots): \n"; std::thread th(do_read_value); std::mutex mtx; std::unique_lock lck(mtx); while (cv.wait_for(lck,std::chrono::seconds(1)) == std::cv_status::timeout) { std::cout << '.'; std::cout.flush(); } std::cout << "You entered: " << value << '\n'; th.join(); return 0; }

std::condition_variable::wait_until 介绍

template 
   
     cv_status wait_until (unique_lock
    
     & lck, const chrono::time_point
     
      & abs_time); template 
      
        bool wait_until (unique_lock
       
        & lck, const chrono::time_point
        
         & abs_time, Predicate pred); 
        
       
      
     
    
   

std::condition_variable::wait_for 类似,但是wait_until可以指定一个时间点,在当前线程收到通知或者指定的时间点 abs_time超时之前,该线程都会处于阻塞状态。而一旦超时或者收到了其他线程的通知,wait_until返回,剩下的处理步骤和 wait_until() 类似。

另外,wait_until的重载版本的最后一个参数 pred表示 wait_until 的预测条件,只有当 pred 条件为 false时调用 wait()才会阻塞当前线程,并且在收到其他线程的通知后只有当predtrue时才会被解除阻塞,因此相当于如下代码:

while (!pred())
  if ( wait_until(lck,abs_time) == cv_status::timeout)
    return pred();
return true;

std::condition_variable::notify_one() 介绍

唤醒某个等待(wait)线程。如果当前没有等待线程,则该函数什么也不做,如果同时存在多个等待线程,则唤醒某个线程是不确定的(unspecified)

请看下例(参考):


#include 
   
     // std::cout #include 
    
      // std::thread #include 
     
       // std::mutex, std::unique_lock #include 
      
        // std::condition_variable std::mutex mtx; std::condition_variable cv; int cargo = 0; // shared value by producers and consumers void consumer() { std::unique_lock < std::mutex > lck(mtx); while (cargo == 0) cv.wait(lck); std::cout << cargo << '\n'; cargo = 0; } void producer(int id) { std::unique_lock < std::mutex > lck(mtx); cargo = id; cv.notify_one(); } int main() { std::thread consumers[10], producers[10]; // spawn 10 consumers and 10 producers: for (int i = 0; i < 10; ++i) { consumers[i] = std::thread(consumer); producers[i] = std::thread(producer, i + 1); } // join them back: for (int i = 0; i < 10; ++i) { producers[i].join(); consumers[i].join(); } return 0; }
      
     
    
   

std::condition_variable::notify_all() 介绍

唤醒所有的等待(wait)线程。如果当前没有等待线程,则该函数什么也不做。请看下面的例子:


#include 
   
     // std::cout #include 
    
      // std::thread #include 
     
       // std::mutex, std::unique_lock #include 
      
        // std::condition_variable std::mutex mtx; // 全局互斥锁. std::condition_variable cv; // 全局条件变量. bool ready = false; // 全局标志位. void do_print_id(int id) { std::unique_lock 
       
         lck(mtx); while (!ready) // 如果标志位不为 true, 则等待... cv.wait(lck); // 当前线程被阻塞, 当全局标志位变为 true 之后, // 线程被唤醒, 继续往下执行打印线程编号id. std::cout << "thread " << id << '\n'; } void go() { std::unique_lock 
        
          lck(mtx); ready = true; // 设置全局标志位为 true. cv.notify_all(); // 唤醒所有线程. } int main() { std::thread threads[10]; // spawn 10 threads: for (int i = 0; i < 10; ++i) threads[i] = std::thread(do_print_id, i); std::cout << "10 threads ready to race...\n"; go(); // go! for (auto & th:threads) th.join(); return 0; }
        
       
      
     
    
   

std::condition_variable_any 介绍

std::condition_variable类似,只不过std::condition_variable_anywait 函数可以接受任何 lockable参数,而 std::condition_variable只能接受 std::unique_lock 类型的参数,除此以外,和std::condition_variable几乎完全一样。

std::cv_status枚举类型介绍

cv_status::no_timeout wait_for 或者wait_until没有超时,即在规定的时间段内线程收到了通知。

cv_status::timeout  wait_for 或者 wait_until 超时。
std::notify_all_at_thread_exit

函数原型为:

void notify_all_at_thread_exit (condition_variable& cond, unique_lock
   
     lck);
   

当调用该函数的线程退出时,所有在 cond 条件变量上等待的线程都会收到通知。请看下例(参考):

#include 
   
     // std::cout #include 
    
      // std::thread #include 
     
       // std::mutex, std::unique_lock #include 
      
        // std::condition_variable std::mutex mtx; std::condition_variable cv; bool ready = false; void print_id (int id) { std::unique_lock
       
         lck(mtx); while (!ready) cv.wait(lck); // ... std::cout << "thread " << id << '\n'; } void go() { std::unique_lock
        
          lck(mtx); std::notify_all_at_thread_exit(cv,std::move(lck)); ready = true; } int main () { std::thread threads[10]; // spawn 10 threads: for (int i=0; i<10; ++i) threads[i] = std::thread(print_id,i); std::cout << "10 threads ready to race...\n"; std::thread(go).detach(); // go! for (auto& th : threads) th.join(); return 0; } 
        
       
      
     
    
   

好了,到此为止, 头文件中的两个条件变量类(std::condition_variablestd::condition_variable_any)、枚举类型(std::cv_status)、以及辅助函数(std::not

首页 上一页 1 2 3 下一页 尾页 2/3/3
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇LeetCode204:Count Primes 下一篇C++入门学习――标准模板库之vect..

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: