(十二)boost库之多线程高级特性
(十二)boost库之多线程高级特性
很多时候,线程不仅仅是执行一些耗时操作,可能我们还需要得到线程的返回值,一般的处理方法就是定义一个全局状态变量,不断轮训状态,就如我目前维护的一个项目,全局变量定义了N中状态,看的让人抓狂。该项目的大体逻辑是这样的,启动K个线程,当线程执行到某一个点时,进行轮训,判断是否所有线程都执行到该点,单独开启了一个线程用于轮训所有线程是否结束,待所有线程结束后会获取数据,生成一个文件,另外还有一个线程就在轮训文件是否生成,然后读取文件进行下一步操作。各种的轮训,显得非常的笨拙。利用boost库,我们来看看这么解决这些同步问题。
1、获取线程结果
boost::packaged_task 包装一个可调用的对象,并且允许异步获取该可调用对象产生的结果
unique_future 用于保存异步计算得到的结果
void GetFutures()
{
boost::packaged_task<int> pt(boost::bind(Fibonacci, 10));
boost::unique_future<int> uf = pt.get_future();
//启动线程,必须使用move,packaged_task是不可拷贝的
boost::thread th(boost::move(pt));
uf.wait();
int nVal = uf.get();
cout << "Fibonacci " << nVal << endl;
}
uf.wait等待线程结束,当然future类也提供了很多种等待函数,如timed_wait等待一段时间。
当然,我们更多的时候是等待一组线程的结束,这是可以用wait_for_all等待所有future对象,wait_for_any 等待任意一个对象接收。
void GetFutures()
{
boost::packaged_task<int> pt1(boost::bind(Fibonacci, 10));
boost::packaged_task<int> pt2(boost::bind(Fibonacci, 20));
boost::unique_future<int> uf1 = pt1.get_future();
boost::unique_future<int> uf2 = pt2.get_future();
boost::thread(boost::move(pt1));
boost::thread(boost::move(pt2));
boost::wait_for_all(uf1, uf2);
cout << "Fibonacci " << uf1.get() << " ," << uf2.get() << endl;
}
2、护栏barrier
护栏就是说要等待所有的线程到达同一个点,才继续往下执行。
boost::barrier br(3);
void BarrierFunc()
{
cout << "begin" << endl;
br.wait();
cout << "end " << endl;
}
void TestBarrier()
{
boost::thread_group grp;
grp.create_thread(BarrierFunc);
grp.create_thread(BarrierFunc);
grp.create_thread(BarrierFunc);
grp.join_all();
}
3、线程本地存储
程序中使用全局变量或局部静态变量,这是非常常见的,但这样的函数对多线程程序来说,很难保证程序的正确性,这时我们希望,这些全局变量和局部静态变量,是线程独立拥有的,多个线程之间不会造成干扰,那么使用thread_specific_ptr就能轻松解决。
int Add(int n)
{
static boost::thread_specific_ptr<int> sp; //该变量是线程独立拥有的
if (!sp.get())
{
sp.reset(new int(0));
}
*sp = n + *sp;
return *sp;
}
void Sum()
{
cout << Add(5) + Add(10) << endl; //得到的结果20
}
void ThreadSum()
{
boost::thread_group threads;
for (int i=0; i<5; ++i)
threads.create_thread(&Sum); //所有线程输出的结果是一样的
threads.join_all();
}
(十二)boost库之多线程高级特性的更多相关文章
- (十)boost库之多线程
(十)boost库之多线程 1.创建线程 使用boost库可以方便的创建一个线程,并提供最多支持9个参数的线程函数,相对于void*来说,方便了很多,创建线程主要提供了一下3种方式: 线程库头文件:# ...
- (十二) 一起学 Unix 环境高级编程 (APUE) 之 进程间通信(IPC)
. . . . . 目录 (一) 一起学 Unix 环境高级编程 (APUE) 之 标准IO (二) 一起学 Unix 环境高级编程 (APUE) 之 文件 IO (三) 一起学 Unix 环境高级编 ...
- 《Android群英传》读书笔记 (5) 第十一章 搭建云端服务器 + 第十二章 Android 5.X新特性详解 + 第十三章 Android实例提高
第十一章 搭建云端服务器 该章主要介绍了移动后端服务的概念以及Bmob的使用,比较简单,所以略过不总结. 第十三章 Android实例提高 该章主要介绍了拼图游戏和2048的小项目实例,主要是代码,所 ...
- (十一)boost库之多线程间通信
(十一)boost库之多线程间通信 1.互斥锁 在编程中,引入了对象互斥锁的概念,来保证共享数据操作的完整性.每个对象都对应于一个可称为" 互斥锁" 的标记,这个标记用来保证在任一 ...
- Android群英传笔记——第十二章:Android5.X 新特性详解,Material Design UI的新体验
Android群英传笔记--第十二章:Android5.X 新特性详解,Material Design UI的新体验 第十一章为什么不写,因为我很早之前就已经写过了,有需要的可以去看 Android高 ...
- 大数据笔记(二十六)——Scala语言的高级特性
===================== Scala语言的高级特性 ========================一.Scala的集合 1.可变集合mutable 不可变集合immutable / ...
- 第十二篇 Integration Services:高级日志记录
本篇文章是Integration Services系列的第十二篇,详细内容请参考原文. 简介在前一篇文章我们配置了SSIS内置日志记录,演示了简单和高级日志配置,保存并查看日志配置,生成自定义日志消息 ...
- 【译】第十二篇 Integration Services:高级日志记录
本篇文章是Integration Services系列的第十二篇,详细内容请参考原文. 简介在前一篇文章我们配置了SSIS内置日志记录,演示了简单和高级日志配置,保存并查看日志配置,生成自定义日志消息 ...
- Python之路【第十二篇】:Python面向对象高级
一.反射 1 什么是反射 反射的概念是由Smith在1982年首次提出的,主要是指程序可以访问.检测和修改它本身状态或行为的一种能力(自省).这一概念的提出很快引发了计算机科学领域关于应用反射性的研究 ...
随机推荐
- Keil C51 中指针的使用
指针是C语言中比较难的一个内容,Keil C51在指针方面有和标准C不一样的地方,今天看了一些资料学习了一下Keil C51 中指针的使用. keil51的指针,包含两种指针:普通指针,兼容标准C:内 ...
- 多线程实际运用<第七篇>
1.单线程采集100个页面 class Program { static int i = 6991275; static void Main(string[] args) { Stopwatch sw ...
- C# 集合性能 总结
一.引言 本文主要记录的是C#各种集合操作的性能,下面的标记说明描述标记的时间,下面的表格对比各种集合各种操作的时间. 标记说明: O(1) 表示无论集合中有多少项,这个操作需要的时间都不变,例如,A ...
- SQL Server 2008空间数据应用系列十:使用存储过程生成GeoRSS聚合空间信息
原文:SQL Server 2008空间数据应用系列十:使用存储过程生成GeoRSS聚合空间信息 友情提示,您阅读本篇博文的先决条件如下: 1.本文示例基于Microsoft SQL Server 2 ...
- Linux学习,在线版
考虑加入Linux教派,最初被Linux吸引是看了<Unix编程艺术>,虽然里面的个别非常教条,极端.但是里面大部分的设计思想我还是认同的. 下面是我整理的一些Linux资料,其实我打算折 ...
- Grid++Report 报表开发工具
Grid++Report 报表开发工具 版本 更新日期 大小 下载 说明 Grid++Repoert6.0.0.6 2015/08/08 16.0M [下载] 锐浪报表工具最新版本,新增功能说 ...
- Isomorphic Strings 解答
Question Given two strings s and t, determine if they are isomorphic. Two strings are isomorphic if ...
- nand烧写分析/内核在启动过程中式如何将这个文件映射成/目录及各子目录的?
我用的是ramdisk.image.gz,烧写在flash的0x10140000处 我不太明白内核在启动过程中式如何将这个文件映射成/目录及各子目录的? 如果ramdisk.image.gz在flas ...
- poj 3894 System Engineer (二分图最大匹配--匈牙利算法)
System Engineer Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 507 Accepted: 217 Des ...
- 多线程:pthread_exit,pthread_join,pthread_self
/*exit_join_id.c*/ #include<pthread.h> #include<stdio.h> void* eji(void* agr) { printf(& ...