C++11并发编程 |
您所在的位置:网站首页 › condition_variable_any › C++11并发编程 |
总结的很详细,打算记录下来。 原文地址:https://www.2cto.com/kf/201506/411327.html 头文件主要包含了与条件变量相关的类和函数。相关的类包括 std::condition_variable和 std::condition_variable_any,还有枚举类型std::cv_status。另外还包括函数 std::notify_all_at_thread_exit(),下面分别介绍一下以上几种类型。 std::condition_variable 类介绍std::condition_variable是条件变量,更多有关条件变量的定义参考维基百科。Linux下使用 Pthread库中的 pthread_cond_*() 函数提供了与条件变量相关的功能, Windows 则参考 MSDN。 当 std::condition_variable对象的某个wait 函数被调用的时候,它使用 std::unique_lock(通过 std::mutex) 来锁住当前线程。当前线程会一直被阻塞,直到另外一个线程在相同的 std::condition_variable 对象上调用了 notification 函数来唤醒当前线程。 std::condition_variable 对象通常使用 std::unique_lock 来等待,如果需要使用另外的 lockable 类型,可以使用std::condition_variable_any类,本文后面会讲到 std::condition_variable_any 的用法。 ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 #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 std::thread threads[10]; // spawn 10 threads: for (int i = 0; i < 10; ++i) threads[i] = std::thread(do_print_id, i);
std::cout for (int i = 0; i < n; ++i) { std::unique_lock lck(mtx); cv.wait(lck, shipment_available); std::cout while (shipment_available()) std::this_thread::yield(); std::unique_lock lck(mtx); cargo = i + 1; cv.notify_one(); }
consumer_thread.join();
return 0; } ? 1 2 3 4 5 6 7 8 9 10 1 2 3 4 5 6 7 8 9 10 std::condition_variable::wait_for() 介绍? 1 2 3 4 5 6 7 template cv_status wait_for (unique_lock& lck, const chrono::duration& rel_time);
template bool wait_for (unique_lock& lck, const chrono::duration& rel_time, Predicate pred); 与std::condition_variable::wait() 类似,不过 wait_for可以指定一个时间段,在当前线程收到通知或者指定的时间 rel_time 超时之前,该线程都会处于阻塞状态。而一旦超时或者收到了其他线程的通知,wait_for返回,剩下的处理步骤和 wait()类似。 另外,wait_for 的重载版本的最后一个参数pred表示 wait_for的预测条件,只有当 pred条件为false时调用 wait()才会阻塞当前线程,并且在收到其他线程的通知后只有当 pred为 true时才会被解除阻塞,因此相当于如下代码: ? 1 return wait_until (lck, chrono::steady_clock::now() + rel_time, std::move(pred)); 请看下面的例子(参考),下面的例子中,主线程等待th线程输入一个值,然后将th线程从终端接收的值打印出来,在th线程接受到值之前,主线程一直等待,每个一秒超时一次,并打印一个 ".": ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 #include // std::cout #include // std::thread #include // std::chrono::seconds #include // std::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 std::unique_lock < std::mutex > lck(mtx); while (cargo == 0) cv.wait(lck); std::cout 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)线程。如果当前没有等待线程,则该函数什么也不做。请看下面的例子: ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 #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 std::thread threads[10]; // spawn 10 threads: for (int i = 0; i < 10; ++i) threads[i] = std::thread(do_print_id, i);
std::cout 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 |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |