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 线程安全的定义 如果多线程下使用这个类,不过多线程如何使用和调度这个类,这个类总是表示出正确的行为,这个类就是线程安全的. 类的线程安全表现为: 操作的原子性 内存的可见性 不 ...
随机推荐
- laravel 集合
最近一直在用laravel框架,比较喜欢laravel的ORM(通常我们理解的Model)...但是默认情况下,Eloquent 查询的结果总是返回 Collection 实例...所有不得不了解co ...
- SPLAY,LCT学习笔记(四)
前三篇好像变成了SPLAY专题... 这一篇正式开始LCT! 其实LCT就是基于SPLAY的伸展操作维护树(森林)连通性的一个数据结构 核心操作有很多,我们以一道题为例: 例:bzoj 2049 洞穴 ...
- Linux下配置自动更新时间
1,修正本地时区及ntp服务 [root@VM_0_13_centos ~]# yum -y install ntp [root@VM_0_13_centos ~]# rm -rf /etc/loca ...
- jmeter在返回的json串中提取需要的值
接口测试时我们需要对某条信息进行修改,如我们先创建了一篇文章,然后进行修改操作 我们就需要找到该文章的唯一标志,如id 示例:我们要将下图返回的json 中id进行提取 注:可输入$.加需要的key即 ...
- Intellij IDEA配置tomcat热部署
idea2017+tomcat8为本文的实验环境 1.打开tomcat的edit configuration,一定要选择war exploded 在idea tomcat 中server的配置里,有 ...
- 算法-----python实现
斐波那契数列 def f(n): if n == 1: return 1 elif n == 2: return 1 else: return f(n-1)+f(n-2) print(f(8)) 用普 ...
- URL中带加号的处理
问题起因: 客户订购了一关键字为"e+h 变送器" , 在首页推荐广告中,会根据用户在search 搜索过的关键字进行一个匹配投放.技术实现是UED 通过JS 获取coo ...
- hdu 2036 求多边形面积 (凸、凹多边形)
<题目链接> Problem Description “ 改革春风吹满地,不会AC没关系;实在不行回老家,还有一亩三分地.谢谢!(乐队奏乐)” 话说部分学生心态极好,每天就知道游戏,这次考 ...
- Web轻量级扫描工具Skipfish
Web轻量级扫描工具Skipfish 1. Skipfish 简介 2. Skipfish 基本操作 3.身份认证 一. Skipfish 简介 Skipfish是一款主动的Web应用程序安全侦察工具 ...
- 初探和实现websocket心跳重连(npm: websocket-heartbeat-js)
提示:文章最下方有仓库地址 心跳重连缘由 websocket是前后端交互的长连接,前后端也都可能因为一些情况导致连接失效并且相互之间没有反馈提醒.因此为了保证连接的可持续性和稳定性,websocket ...