[并发编程]使用线程安全队列和条件变量的notify来安排分步骤任务
// 方法1:直接构建N个THread来run
foreach (i, size)
{
thread trd(&Instance::doWork, &inst);
lstTrd.push_back(trd);
} foreach(lstTrd, join); // 方法2:使用notify的方式来处理分步骤任务 class threadsafe_queue
{
queue<int> q;
mutex m;
condition_variable cond;
public:
void push(int i)
{
lock_guard<mutex> lk(m);
q.push_back(i);
cond.notify_one();
} void wait_and_pop(int &i)
{
unique_lock<mutex> lk(m);
cond.wait(lk, [this]{ return !q.empty(); } );
i = q.front();
q.pop();
}
} class Instance
{
// 存储原始的用于处理的n个数目的数据
List<GDSLayer> lstInfo;
...
// 存储最终的数据(其实应该每个步骤都有中间过程数据产生)
List<Result> lstResult; // 每个步骤完成就往对应的queue里面把完成的数据的index插入,而下一个线程就在等待这个队列有元素
// 于是对于数据index = 0就会进行:A->B->C...
threadsafe_queue merge_q;
threadsafe_queue match_q;
threadsafe_queue GDSPinGen_q;
threadsafe_queue OBSGen_q;
threadsafe_queue LEFPin_q;
public:
void merge_thread()
{
// 如果发生错误,那么是否要符合没有到size也可以退出
// 事先是否要把所有可能的操作数的空间都分配好,免得如果先操作0,结果notify到了3,然后操作3,虽然原始数据有,但存储过程数据还没有
// 同时,Log信息处理是否可行?中间检查信息的操作是安全的吗?
// 但这样,每个thread只负责一个步骤,处理完一个数据才处理下一个(是否如此?)按理来说是不会存在跨越的问题
foreach (i, lstInfo.size())
{
bool b_state = doMerge(lstInfo[i]);
if (b_state)
merge_q.push_back(i);
}
} void match_thread()
{
foreach(i, lstInfo.size())
{
int key = -;
merge_q.wait_and_pop(key);
bool b_state = doMatch( lstInfo[ key ] );
if (b_state)
{
match_q.push_back( key );
}
}
} void GDSPinGen_thread()
{} void OBSGen_thread()
{} void LEFPin_thread()
{}
}
方法3:使用async
方法4:使用package_task
方法5:使用promise
方法6:使用线程池
[并发编程]使用线程安全队列和条件变量的notify来安排分步骤任务的更多相关文章
- Java并发编程:线程池的使用
Java并发编程:线程池的使用 在前面的文章中,我们使用线程的时候就去创建一个线程,这样实现起来非常简便,但是就会有一个问题: 如果并发的线程数量很多,并且每个线程都是执行一个时间很短的任务就结束了, ...
- 并发编程 13—— 线程池的使用 之 配置ThreadPoolExecutor 和 饱和策略
Java并发编程实践 目录 并发编程 01—— ThreadLocal 并发编程 02—— ConcurrentHashMap 并发编程 03—— 阻塞队列和生产者-消费者模式 并发编程 04—— 闭 ...
- Java并发编程:线程池的使用(转)
Java并发编程:线程池的使用 在前面的文章中,我们使用线程的时候就去创建一个线程,这样实现起来非常简便,但是就会有一个问题: 如果并发的线程数量很多,并且每个线程都是执行一个时间很短的任务就结束了, ...
- Java并发编程:线程池的使用(转载)
转载自:https://www.cnblogs.com/dolphin0520/p/3932921.html Java并发编程:线程池的使用 在前面的文章中,我们使用线程的时候就去创建一个线程,这样实 ...
- Java并发编程:线程池的使用(转载)
文章出处:http://www.cnblogs.com/dolphin0520/p/3932921.html Java并发编程:线程池的使用 在前面的文章中,我们使用线程的时候就去创建一个线程,这样实 ...
- [转]Java并发编程:线程池的使用
Java并发编程:线程池的使用 在前面的文章中,我们使用线程的时候就去创建一个线程,这样实现起来非常简便,但是就会有一个问题: 如果并发的线程数量很多,并且每个线程都是执行一个时间很短的任务就结束了, ...
- 【转】Java并发编程:线程池的使用
Java并发编程:线程池的使用 在前面的文章中,我们使用线程的时候就去创建一个线程,这样实现起来非常简便,但是就会有一个问题: 如果并发的线程数量很多,并且每个线程都是执行一个时间很短的任务就结束了, ...
- 13、Java并发编程:线程池的使用
Java并发编程:线程池的使用 在前面的文章中,我们使用线程的时候就去创建一个线程,这样实现起来非常简便,但是就会有一个问题: 如果并发的线程数量很多,并且每个线程都是执行一个时间很短的任务就结束了, ...
- Java并发编程:线程间协作的两种方式:wait、notify、notifyAll和Condition
Java并发编程:线程间协作的两种方式:wait.notify.notifyAll和Condition 在前面我们将了很多关于同步的问题,然而在现实中,需要线程之间的协作.比如说最经典的生产者-消费者 ...
随机推荐
- SVG
目前SVG在国内的使用并不常见,并且关于svg的相关js库也不多,这里指出两款svg的库Snap.svg和svg.js,Snap.svg张鑫旭的博客上有关于他的使用APi http://www.zha ...
- 微信公众号-加解密数据demo坑
demo里面的MsgSignature作为url参数一部分了,demo也不更新下 坑爹的微信! 解密信息部分 include_once "wxBizMsgCrypt.php"; $ ...
- PHP保存base64
base64图片格式:$base64_url = data:image/jpeg;base64,xxxxxxxxxxxxxxxxxxxxxx 1,去除头部:$base64_body = substr( ...
- linux 中 ‘|’的作用
利用Linux所提供的管道符“|”将两个命令隔开,管道符左边命令的输出就会作为管道符右边命令的输入.连续使用管道意味着第一个命令的输出会作为 第二个命令的输入,第二个命令的输出又会作为第三个命令的输入 ...
- 四句话总结JavaScript作用域
上一篇文章中简单介绍了一下JS作用域,本篇将作进一步探究和总结. 前言:JavaScript的作用域一直以来都是前端开发中比较难以理解的知识点,JavaScript6中新引入了 let 关键字,用于指 ...
- ObjectCopy
对象的传参用的是传引用,但开发中通常不允许对传入参数进行修改.因此对象拷贝很常用,Python提供一个很方便的对象拷贝方法 如代码: __author__ = 'mengxuan' import co ...
- C++的类和对象
#include <iostream> // 预处理命令 using namespace std; class Student{ // 声明一个类,类名为Student private : ...
- Android用户界面 UI组件--TextView及其子类(二) Button,selector选择器,sharp属性
1.XML文件中的OnClick 属性可以指定在Activity中处理点击事件的方法,Activity中必须定义该属性指定的值作为方法的名字且有一个View类型的参数,表示此物件被点击. 2.使用se ...
- Android4.0以下View的Drag和Drop简单实现
主要代码部分: 实现View的onTouch方法,变换落点的X,Y坐标,定义两个变量存放拖动前的坐标位置. int prevX,prevY; @Override public boolean onTo ...
- 在ListView中使用多个布局
要想在一个ListView中使用多个布局文件,比如一个信息List包含了一个信息标题和每个信息对应的时间. 关键的步骤是实现Adapter类的getItemViewType 和getViewTypeC ...