C++并发编程 条件变量 condition_variable,线程安全队列示例
1. 背景
c++11中提供了对线程与条件变量的更好支持,对于写多线程程序方便了很多。
再看c++并发编程,记一下学习笔记。
2. c++11 提供的相关api
3.1 wait
wait用于无条件等待,其中Predicate表示校验条件,可以避免假唤醒。
unconditional (1)
void wait (unique_lock<mutex>& lck);
predicate (2)
template <class Predicate>
void wait (unique_lock<mutex>& lck, Predicate pred);
3.2 wait for
wait_for可以指定超时时间,其中Predicate表示校验条件,可以避免假唤醒。
unconditional (1)
template <class Rep, class Period>
cv_status wait_for (unique_lock<mutex>& lck,
const chrono::duration<Rep,Period>& rel_time);
predicate (2)
template <class Rep, class Period, class Predicate>
bool wait_for (unique_lock<mutex>& lck,
const chrono::duration<Rep,Period>& rel_time, Predicate pred);
3. 线程安全队列示例(生产者与消费者模型)
一个生产者向队列中添加数据;多个消费者从队列中读取任务。
#include <mutex>
#include <condition_variable>
#include <queue>
#include <vector>
#include <thread>
#include <iostream>
template<typename T>
class threadsafe_queue
{
private:
std::mutex mut;
std::queue<T> data_queue;
std::condition_variable data_cond;
public:
threadsafe_queue(){ }
void push(T new_value) {
std::lock_guard<std::mutex> lk(mut);
data_queue.push(new_value);
data_cond.notify_one();
}
//无限等待
int pop(T& value) {
std::unique_lock<std::mutex> lk(mut);
// (1) 带判断条件的wait, 条件不满足则继续等待; 满足则继续后续代码
data_cond.wait(lk,[this]{return !data_queue.empty();});
// (2)wait唤醒后需要再次判断, 避免假唤醒
//while(true){
// data_cond.wait(lk);
// if (data_queue.empty())
// continue;
// else
// break;
//}
value=data_queue.front();
data_queue.pop();
return 0;
}
//有限等待
int pop_with_timeout(T& value, int timeout) {
if (timeout < 0){
return this->pop(value);
}
std::unique_lock<std::mutex> lk(mut);
//带超时, 带判断条件的wait
data_cond.wait_for(lk, std::chrono::milliseconds(timeout), [this] {
std::cout << "thread id: " << std::this_thread::get_id() << " wait..." << std::endl;
return !data_queue.empty();}
);
if (!data_queue.empty()){
value=data_queue.front();
data_queue.pop();
return 0;
}
return -1;
}
bool is_empty(){
std::lock_guard<std::mutex> lk(mut);
return data_queue.empty();
}
};
template<typename T>
void consume(threadsafe_queue<T> &queue, bool &stop){
while(true){
if (stop && queue.is_empty()){ //结束条件
break;
}
int job_id = 0;
if (0 == queue.pop_with_timeout(job_id, 3)){
std::cout << "thread id: " << std::this_thread::get_id() << ", job:" << job_id << std::endl;
}
std::this_thread::sleep_for (std::chrono::milliseconds(5));
}
}
template<typename T>
void product(threadsafe_queue<T> &queue, bool &stop){
for (auto i = 0; i < 100; ++i){
queue.push(i);
std::this_thread::sleep_for (std::chrono::milliseconds(1));
}
stop = true; //设置结束条件
}
int main(){
threadsafe_queue<int> my_queue;
bool stop_flag = false;
//生产者
std::thread prod(product<int>, std::ref(my_queue), std::ref(stop_flag));
//消费者
std::vector<std::thread> cons;
for(auto i = 0; i < 5; ++i){
std::thread tmp = std::thread(consume<int>, std::ref(my_queue), std::ref(stop_flag));
cons.emplace_back(std::move(tmp));
}
prod.join();
for(auto &t : cons){
t.join();
}
return 0;
}
C++并发编程 条件变量 condition_variable,线程安全队列示例的更多相关文章
- Windows:C++11并发编程-条件变量(condition_variable)详解
<condition_variable >头文件主要包含了与条件变量相关的类和函数.相关的类包括 std::condition_variable和 std::condition_varia ...
- C++11并行编程-条件变量(condition_variable)详细说明
<condition_variable >头文件主要包含有类和函数相关的条件变量. 包括相关类 std::condition_variable和 std::condition_variab ...
- linux 条件变量与线程池
条件变量Condition Variables 概述 1. 条件变量提供了另外一种线程同步的方式.如果没有条件变量,程序需要使用线程连续轮询(可能在临界区critical section内)方式检查条 ...
- Java并发编程系列-(6) Java线程池
6. 线程池 6.1 基本概念 在web开发中,服务器需要接受并处理请求,所以会为一个请求来分配一个线程来进行处理.如果每次请求都新创建一个线程的话实现起来非常简便,但是存在一个问题:如果并发的请求数 ...
- [ 高并发]Java高并发编程系列第二篇--线程同步
高并发,听起来高大上的一个词汇,在身处于互联网潮的社会大趋势下,高并发赋予了更多的传奇色彩.首先,我们可以看到很多招聘中,会提到有高并发项目者优先.高并发,意味着,你的前雇主,有很大的业务层面的需求, ...
- Java并发编程:如何创建线程?
Java并发编程:如何创建线程? 在前面一篇文章中已经讲述了在进程和线程的由来,今天就来讲一下在Java中如何创建线程,让线程去执行一个子任务.下面先讲述一下Java中的应用程序和进程相关的概念知识, ...
- 2、Java并发编程:如何创建线程
Java并发编程:如何创建线程? 在前面一篇文章中已经讲述了在进程和线程的由来,今天就来讲一下在Java中如何创建线程,让线程去执行一个子任务.下面先讲述一下Java中的应用程序和进程相关的概念知识, ...
- conditon_variable(条件变量)用于线程间同步
conditon_variable(条件变量)用于线程间同步 condition_variable有5个函数,函数名及对应的功能如下: wait阻塞自己,等待唤醒 wait_for阻塞自己,等待唤醒, ...
- Java并发编程系列-(7) Java线程安全
7. 线程安全 7.1 线程安全的定义 如果多线程下使用这个类,不过多线程如何使用和调度这个类,这个类总是表示出正确的行为,这个类就是线程安全的. 类的线程安全表现为: 操作的原子性 内存的可见性 不 ...
随机推荐
- jsonp原理和实例详解
1.一个众所周知的问题,Ajax直接请求普通文件存在跨域无权限访问的问题,甭管你是静态页面.动态网页.web服务.WCF,只要是跨域请求,一律不准:2.不过我们又发现,Web页面上调用js文件时则不受 ...
- Thread + 匿名内部类
package chapter01; public class MyThread01 extends Thread{ @Override public void run() { //让当前线程执行的代 ...
- ORACLE 计算时间相减间隔
在Oralce中我发现有add_months函数,加天数N可以用如下方法实现,select sysdate+N from dual 在Oralce中我发现有add_months函数,加天数N可以用如下 ...
- 2018-2019-2 网络对抗技术 20165333 Exp2 后门原理与实践
实验内容 1.使用netcat获取主机操作Shell,cron启动 2.使用socat获取主机操作Shell, 任务计划启动 3.使用MSF meterpreter(或其他软件)生成可执行文件,利用n ...
- java:冒泡排序、选择排序、插入排序实现
整数排序 给一组整数,按照升序排序,使用选择排序,冒泡排序,插入排序或者任何 O(n2) 的排序算法. 样例 样例 1: 输入: [3, 2, 1, 4, 5] 输出: [1, 2, 3, 4, 5] ...
- 7-4素数环 uva 524
#include<iostream> #include<cstdio> #include<cmath> #include<cstring> using ...
- turbo boost - 睿频加速
turbo boost就是英特尔睿频加速技术 英特尔睿频加速技术是英特尔酷睿 i7/i5 处理器的独有特性,也是英特尔新宣布的一项技术.这项技术可以理解为自动超频.当开启睿频加速之后,CPU会根据当前 ...
- ListView优化中的细节问题
1.android:layout_height属性: 必须将ListView的布局高度属性设置为非“wrap_content”(可以是“match_parent / fill_parent / ...
- POJ 2752 (kmp求所有公共前后缀长度)
<题目链接> <转载于> 题目大意: 给出一个字符串str,求出str中存在多少子串,使得这些子串既是str的前缀,又是str的后缀.从小到大依次输出这些子串的长度.即输出该 ...
- 洛谷 P1464 Function【记忆化搜索】
题目链接 题目描述 对于一个递归函数w(a,b,c) 如果a<=0 or b<=0 or c<=0就返回值1. 如果a>20 or b>20 or c>20就返回w ...