(十二)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库之多线程高级特性的更多相关文章

  1. (十)boost库之多线程

    (十)boost库之多线程 1.创建线程 使用boost库可以方便的创建一个线程,并提供最多支持9个参数的线程函数,相对于void*来说,方便了很多,创建线程主要提供了一下3种方式: 线程库头文件:# ...

  2. (十二) 一起学 Unix 环境高级编程 (APUE) 之 进程间通信(IPC)

    . . . . . 目录 (一) 一起学 Unix 环境高级编程 (APUE) 之 标准IO (二) 一起学 Unix 环境高级编程 (APUE) 之 文件 IO (三) 一起学 Unix 环境高级编 ...

  3. 《Android群英传》读书笔记 (5) 第十一章 搭建云端服务器 + 第十二章 Android 5.X新特性详解 + 第十三章 Android实例提高

    第十一章 搭建云端服务器 该章主要介绍了移动后端服务的概念以及Bmob的使用,比较简单,所以略过不总结. 第十三章 Android实例提高 该章主要介绍了拼图游戏和2048的小项目实例,主要是代码,所 ...

  4. (十一)boost库之多线程间通信

    (十一)boost库之多线程间通信 1.互斥锁 在编程中,引入了对象互斥锁的概念,来保证共享数据操作的完整性.每个对象都对应于一个可称为" 互斥锁" 的标记,这个标记用来保证在任一 ...

  5. Android群英传笔记——第十二章:Android5.X 新特性详解,Material Design UI的新体验

    Android群英传笔记--第十二章:Android5.X 新特性详解,Material Design UI的新体验 第十一章为什么不写,因为我很早之前就已经写过了,有需要的可以去看 Android高 ...

  6. 大数据笔记(二十六)——Scala语言的高级特性

    ===================== Scala语言的高级特性 ========================一.Scala的集合 1.可变集合mutable 不可变集合immutable / ...

  7. 第十二篇 Integration Services:高级日志记录

    本篇文章是Integration Services系列的第十二篇,详细内容请参考原文. 简介在前一篇文章我们配置了SSIS内置日志记录,演示了简单和高级日志配置,保存并查看日志配置,生成自定义日志消息 ...

  8. 【译】第十二篇 Integration Services:高级日志记录

    本篇文章是Integration Services系列的第十二篇,详细内容请参考原文. 简介在前一篇文章我们配置了SSIS内置日志记录,演示了简单和高级日志配置,保存并查看日志配置,生成自定义日志消息 ...

  9. Python之路【第十二篇】:Python面向对象高级

    一.反射 1 什么是反射 反射的概念是由Smith在1982年首次提出的,主要是指程序可以访问.检测和修改它本身状态或行为的一种能力(自省).这一概念的提出很快引发了计算机科学领域关于应用反射性的研究 ...

随机推荐

  1. 关于MySql链接url参数的设置

    jdbc.driverClassName=com.mysql.jdbc.Driverjdbc.url=jdbc:mysql://localhost:3306/database?useUnicode=t ...

  2. UVA 712-S-Trees(满二叉树的简单查询)

    题意:给一棵满二叉树,叶子节点赋予权值,0或者1,对于每个查询输出叶子节点的权值,每个查询0代表往左走,1代表往右走,这题坑的地方是层的访问顺序,如第二组测试,由上到下依次是x3,x1,x2,假如给一 ...

  3. python 性能优化

    1.优化循环 循环之外能做的事不要放在循环内,比如下面的优化可以快一倍 2.使用join合并迭代器中的字符串 join对于累加的方式,有大约5倍的提升 3.使用if is 使用if is True比i ...

  4. Spring的IOC

    引用:http://www.cnblogs.com/xdp-gacl/p/4249939.html 学习过Spring框架的人一定都会听过Spring的IoC(控制反转) .DI(依赖注入)这两个概念 ...

  5. kiki's game

    欢迎参加——BestCoder周年纪念赛(高质量题目+多重奖励) kiki's game Time Limit: 5000/1000 MS (Java/Others)    Memory Limit: ...

  6. minicom与USB转串口

    实验器材:mini6410 连接方式:ARM板通过USB转串口线连接到pc机 下面是具体的设置了. 默认情况下,UBUNTU安装了USB转串口驱动(pl2303). 1.# lsmod | grep ...

  7. ASCII码表完整版

        ASCII值 控制字符 ASCII值 控制字符 ASCII值 控制字符 ASCII值 控制字符 0 NUT 32 (space) 64 @ 96 . 1 SOH 33 ! 65 A 97 a ...

  8. JavaScript 原型链的一点想法

    JavaScript借鉴了许多语言的特点:例如语法类Java.函数借鉴Scheme.原型继承借鉴自Self.正则表达式借鉴于Perl.(DC Javascript:语言精粹).      首先,每个J ...

  9. 配置Apache2 管理 SVN

    软件环境:CentOS-7-x86_64 1.安装 mod_dav_svn   模块 2.在Apache2下增加管理配置,如: cd /etc/httpd/conf.d vim subversion. ...

  10. VS C4819 编译错误解决方法

    偶尔用别人的代码,出现: warning C4819: The file contains a character that cannot be represented ). Save the fil ...