《C++并发编程实战》读书笔记(1)
2016-07-21 11:59
357 查看
这两天开始看《C++并发编程实战》一书,感觉受益匪浅啊!
按照书中的同步并发操作(第四章)的内容,尝试编写线程安全的队列,模拟固定采集时间和不确定处理时间下的队列行为,供大家参考。
用到的C++多线程相关的主要内容为:mutex类(锁对象),lock_guard模板(实现锁对象的RAII用法),unique_lock模版,condition_variable类(用于进程间等待与唤醒)
另外,书中提供了非常好的技巧,如mutex对象在类中设置为mutable(可变),以用于静态成员函数等。
上代码,线程安全队列部分参考书上写的,仅供大家学习交流。
这个是threadsafe_queue的头文件:
#ifndef SQUEUE
#define SQUEUE
#include <queue>
#include <mutex>
#include <condition_variable>
#include <memory>
template<typename T>
class threadsafe_queue{
private:
mutable std::mutex mut;
std::queue<T> data_queue;
std::condition_variable data_cond;
public:
threadsafe_queue() = default;
threadsafe_queue(const threadsafe_queue &other){
std::lock_guard<std::mutex> lk(other.mut);
data_queue = other.data_queue;
}
threadsafe_queue &operator=(const threadsafe_queue &other){
std::lock_guard<std::mutex> lk(other.mut);
data_queue = other.data_queue;
}
void push(T new_val){
std::lock_guard<std::mutex> lk(mut);
data_queue.push(new_val);
data_cond.notify_all();
}
void wait_and_pop(T &value){
std::unique_lock<std::mutex> lk(mut);
data_cond.wait(lk, [this](){return !data_queue.empty(); });
value = data_queue.front();
data_queue.pop();
}
std::shared_ptr<T> wait_and_pop(){
std::unique_lock<std::mutex> lk(mut);
data_cond.wait(lk, [this](){return !data_queue.empty()});
std::shared_ptr<T> ptr(std::make_shared<T>(data_queue.front()));
data_queue.pop();
return ptr;
}
bool try_pop(T &value){
std::lock_guard<std::mutex> lk(mut);
if (data_queue.empty())
return false;
value = data_queue.front();
data_queue.pop();
return true;
}
std::shared_ptr<T> try_pop(){
std::lock_guard<std::mutex> lk(mut);
if (data_queue.empty())
return std::shared_ptr<T>();
std::shared_ptr<T> ptr(std::make_shared<T>(data_queue.front()));
data_queue.pop();
return ptr;
}
bool empty() const{
std::lock_guard<std::mutex> lk(mut);
return data_queue.empty();
}
int size() const{
std::lock_guard<std::mutex> lk(mut);
return data_queue.size();
}
};
#endif
测试代码:
#include "S_queue.h"
#include <vector>
#include <iostream>
#include <thread>
#include <string>
#include <random>
#include <condition_variable>
using namespace std;
void fun1(int value, threadsafe_queue<int> &iq){
uniform_int_distribution<int> u(-100, 100);
default_random_engine e(time(0));
for (int i = 0; i != value; --i){
this_thread::sleep_for(chrono::milliseconds(100));
iq.push(u(e));
}
}
void fun2(int value, threadsafe_queue<int> &iq){
uniform_int_distribution<int> u(90, 105);
default_random_engine e(time(0));
for (int i = 0; i != value; --i){
this_thread::sleep_for(chrono::milliseconds(u(e)));
int val;
cout << "Size: " << iq.size() << " —— ";
iq.wait_and_pop(val);
cout << "Value: " << val << endl;
}
}
int _tmain(int argc, _TCHAR* argv[])
{
string line;
threadsafe_queue<int> iq;
int num;
cin >> num;
thread t1(fun1, num, ref(iq)), t2(fun2, num, ref(iq));
t1.join();
t2.detach();
cin >> line;
return 0;
}
按照书中的同步并发操作(第四章)的内容,尝试编写线程安全的队列,模拟固定采集时间和不确定处理时间下的队列行为,供大家参考。
用到的C++多线程相关的主要内容为:mutex类(锁对象),lock_guard模板(实现锁对象的RAII用法),unique_lock模版,condition_variable类(用于进程间等待与唤醒)
另外,书中提供了非常好的技巧,如mutex对象在类中设置为mutable(可变),以用于静态成员函数等。
上代码,线程安全队列部分参考书上写的,仅供大家学习交流。
这个是threadsafe_queue的头文件:
#ifndef SQUEUE
#define SQUEUE
#include <queue>
#include <mutex>
#include <condition_variable>
#include <memory>
template<typename T>
class threadsafe_queue{
private:
mutable std::mutex mut;
std::queue<T> data_queue;
std::condition_variable data_cond;
public:
threadsafe_queue() = default;
threadsafe_queue(const threadsafe_queue &other){
std::lock_guard<std::mutex> lk(other.mut);
data_queue = other.data_queue;
}
threadsafe_queue &operator=(const threadsafe_queue &other){
std::lock_guard<std::mutex> lk(other.mut);
data_queue = other.data_queue;
}
void push(T new_val){
std::lock_guard<std::mutex> lk(mut);
data_queue.push(new_val);
data_cond.notify_all();
}
void wait_and_pop(T &value){
std::unique_lock<std::mutex> lk(mut);
data_cond.wait(lk, [this](){return !data_queue.empty(); });
value = data_queue.front();
data_queue.pop();
}
std::shared_ptr<T> wait_and_pop(){
std::unique_lock<std::mutex> lk(mut);
data_cond.wait(lk, [this](){return !data_queue.empty()});
std::shared_ptr<T> ptr(std::make_shared<T>(data_queue.front()));
data_queue.pop();
return ptr;
}
bool try_pop(T &value){
std::lock_guard<std::mutex> lk(mut);
if (data_queue.empty())
return false;
value = data_queue.front();
data_queue.pop();
return true;
}
std::shared_ptr<T> try_pop(){
std::lock_guard<std::mutex> lk(mut);
if (data_queue.empty())
return std::shared_ptr<T>();
std::shared_ptr<T> ptr(std::make_shared<T>(data_queue.front()));
data_queue.pop();
return ptr;
}
bool empty() const{
std::lock_guard<std::mutex> lk(mut);
return data_queue.empty();
}
int size() const{
std::lock_guard<std::mutex> lk(mut);
return data_queue.size();
}
};
#endif
测试代码:
#include "S_queue.h"
#include <vector>
#include <iostream>
#include <thread>
#include <string>
#include <random>
#include <condition_variable>
using namespace std;
void fun1(int value, threadsafe_queue<int> &iq){
uniform_int_distribution<int> u(-100, 100);
default_random_engine e(time(0));
for (int i = 0; i != value; --i){
this_thread::sleep_for(chrono::milliseconds(100));
iq.push(u(e));
}
}
void fun2(int value, threadsafe_queue<int> &iq){
uniform_int_distribution<int> u(90, 105);
default_random_engine e(time(0));
for (int i = 0; i != value; --i){
this_thread::sleep_for(chrono::milliseconds(u(e)));
int val;
cout << "Size: " << iq.size() << " —— ";
iq.wait_and_pop(val);
cout << "Value: " << val << endl;
}
}
int _tmain(int argc, _TCHAR* argv[])
{
string line;
threadsafe_queue<int> iq;
int num;
cin >> num;
thread t1(fun1, num, ref(iq)), t2(fun2, num, ref(iq));
t1.join();
t2.detach();
cin >> line;
return 0;
}
相关文章推荐
- 使用C++实现JNI接口需要注意的事项
- Python3写爬虫(四)多线程实现数据爬取
- 关于指针的一些事情
- c++ primer 第五版 笔记前言
- share_ptr的几个注意点
- C#实现多线程的同步方法实例分析
- Lua中调用C++函数示例
- 浅谈chuck-lua中的多线程
- Lua教程(一):在C++中嵌入Lua脚本
- Lua教程(二):C++和Lua相互传递数据示例
- C#简单多线程同步和优先权用法实例
- C#多线程学习之(四)使用线程池进行多线程的自动管理
- C#多线程编程中的锁系统(三)
- 解析C#多线程编程中异步多线程的实现及线程池的使用
- C#多线程学习之(六)互斥对象用法实例
- 基于一个应用程序多线程误用的分析详解
- C++联合体转换成C#结构的实现方法
- C#多线程学习之(三)生产者和消费者用法分析
- C#多线程学习之(一)多线程的相关概念分析
- C#多线程之Thread中Thread.IsAlive属性用法分析