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,线程安全队列示例的更多相关文章

  1. Windows:C++11并发编程-条件变量(condition_variable)详解

    <condition_variable >头文件主要包含了与条件变量相关的类和函数.相关的类包括 std::condition_variable和 std::condition_varia ...

  2. C++11并行编程-条件变量(condition_variable)详细说明

    <condition_variable >头文件主要包含有类和函数相关的条件变量. 包括相关类 std::condition_variable和 std::condition_variab ...

  3. linux 条件变量与线程池

    条件变量Condition Variables 概述 1. 条件变量提供了另外一种线程同步的方式.如果没有条件变量,程序需要使用线程连续轮询(可能在临界区critical section内)方式检查条 ...

  4. Java并发编程系列-(6) Java线程池

    6. 线程池 6.1 基本概念 在web开发中,服务器需要接受并处理请求,所以会为一个请求来分配一个线程来进行处理.如果每次请求都新创建一个线程的话实现起来非常简便,但是存在一个问题:如果并发的请求数 ...

  5. [ 高并发]Java高并发编程系列第二篇--线程同步

    高并发,听起来高大上的一个词汇,在身处于互联网潮的社会大趋势下,高并发赋予了更多的传奇色彩.首先,我们可以看到很多招聘中,会提到有高并发项目者优先.高并发,意味着,你的前雇主,有很大的业务层面的需求, ...

  6. Java并发编程:如何创建线程?

    Java并发编程:如何创建线程? 在前面一篇文章中已经讲述了在进程和线程的由来,今天就来讲一下在Java中如何创建线程,让线程去执行一个子任务.下面先讲述一下Java中的应用程序和进程相关的概念知识, ...

  7. 2、Java并发编程:如何创建线程

    Java并发编程:如何创建线程? 在前面一篇文章中已经讲述了在进程和线程的由来,今天就来讲一下在Java中如何创建线程,让线程去执行一个子任务.下面先讲述一下Java中的应用程序和进程相关的概念知识, ...

  8. conditon_variable(条件变量)用于线程间同步

    conditon_variable(条件变量)用于线程间同步 condition_variable有5个函数,函数名及对应的功能如下: wait阻塞自己,等待唤醒 wait_for阻塞自己,等待唤醒, ...

  9. Java并发编程系列-(7) Java线程安全

    7. 线程安全 7.1 线程安全的定义 如果多线程下使用这个类,不过多线程如何使用和调度这个类,这个类总是表示出正确的行为,这个类就是线程安全的. 类的线程安全表现为: 操作的原子性 内存的可见性 不 ...

随机推荐

  1. jQuery Ajax实例各种使用方法详解

    在jquery中ajax实现方法分类很多种,如有:load.jQuery.get.jQuery.post.jQuery.getScript.jQuery Ajax 事件.jQuery.ajaxSetu ...

  2. Laravel firstOrNew 与 firstOrCreate 的区别

    例如: $item = App\Deployment::firstOrNew( ['name' => '问答小程序'], ['delayed' => 1] ); firstOrNew 需要 ...

  3. Linux学习笔记:使用ftp命令上传和下载文件

    Linux中如何使用ftp命令,包括如何连接ftp服务器,上传or下载文件以及创建文件夹.虽然现在有很多ftp桌面应用(例如:FlashFXP),但是在服务器.SSH.远程会话中掌握命令行ftp的使用 ...

  4. 《剑指offer》-旋转数组的最小数字

    把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转. 输入一个非递减排序的数组的一个旋转,输出旋转数组的最小元素. 例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数 ...

  5. pyinstaller将py文件转成exe格式

    首先要注意一下:打包python文件成exe格式这个过程只能在windows环境下运行 1. 直接在命令行用pip安装 pyinstaller pip install pyinstaller 2. 下 ...

  6. 设置Eclipse的类文件和xml文件代码自动补全

    原文:https://blog.csdn.net/erlian1992/article/details/53706736 我们在平常编写代码的时候,不会记住大多数的类和文件的属性,方法等等,这就需要我 ...

  7. Codeforces 1102F Elongated Matrix 状压dp

    Elongated Matrix 预处理一下两两之间的最小值, 然后直接dp. #include<bits/stdc++.h> #define LL long long #define f ...

  8. BZOJ1201 [HNOI2005]数三角形 大力出奇迹

    欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ1201 题意概括 题解 n3跑过去了,大力出奇迹!简单的,不多说了. 代码 #include < ...

  9. (转)一位资深程序员大牛给予Java初学者的学习路线建议

    原文:http://geek.csdn.net/news/detail/238256 Java学习这一部分其实也算是今天的重点,这一部分用来回答很多群里的朋友所问过的问题,那就是你是如何学习Java的 ...

  10. 实现分布式服务注册及简易的netty聊天

    现在很多地方都会用到zookeeper, 用到它的地方就是为了实现分布式.用到的场景就是服务注册,比如一个集群服务器,需要知道哪些服务器在线,哪些服务器不在线. ZK有一个功能,就是创建临时节点,当机 ...