1、thread的使用

boost的thread包含了线程创建、使用、同步等内容,使用thread需要包含头文件"boost\thread.hpp"。

thread中使用了需要编译的thread库,所以还需要添加thread库到项目附加库目录,在linux下链接thread库时还需要使用-lpthread选项来链接posix线程库。

定义一个thread对象后,线程就开始执行。thread构造函数的第一个参数是一个函数或函数对象或function对象,剩余参数是传递给执行函数或函数对象的参数, 如果希望是引用传递的话则需要配合使用ref。

成员函数join()和timed_join()可以用来阻塞等待线程执行结束,其中timed_join()可以指定等待时间。成员函数detach()的功能类似于posix的pthread_detach():创建一个线程后默认的状态是joinable, 如果一个线程结束运行但没有被join,会有一部分资源没有被回收。可以在创建线程后调用detach()将线程执行体分离,这样该线程运行结束后会自动释放所有资源,而不必使用join来阻塞等待线程结束。调用detach()将线程执行体分离后,成员函数joinable()会返回false,即线程的状态是非状态是非joinable。

需要注意的是thread对象时不可拷贝的。

#include "boost\thread.hpp"

void PrintThreadFunc(const int& n, const string& str)
{
cout << str << n << endl;
} int main()
{
int n1 = ;
string str1 = "hello";
boost::thread t1(PrintThreadFunc, ref(n1), ref(str1)); int n2 = ;
string str2 = "boost";
function<void()> fun = bind(PrintThreadFunc, ref(n2), ref(str2));
boost::thread t2(fun); t1.timed_join(boost::posix_time::seconds()); //最多等待1秒
t2.join(); //一直等待 return ;
}

 2、线程的一些操作

可以调用成员函数get_id()获得线程ID,线程ID提供了比较操作符和流输出操作,因此可以作为标准容器的元素。当一个线程的状态是joinable的,那么可以调用成员函数get_id()获得线程ID,线程ID提供了比较操作符和流输出操作,因此可以作为标准容器的元素。如果调用了成员函数detach()将线程执行体分离,那么get_id()获得的线程ID与静态函数thread::id()的返回值相同。

静态函数this_thread::get_id()可以获得当前线程的线程ID。

静态函数thread::this_thread::sleep()可以让当前线程睡眠一段时间或到指定时间,

静态函数thread::hardware_concurrency()可以获得当前CPU的内核数量。

静态函数this_thread::yield()指示当前线程放弃时间片,允许其他线程运行。

    boost::this_thread::sleep(boost::posix_time::seconds()); //睡眠2秒
cout << boost::this_thread::get_id() << endl; //输出当前线程ID
cout << boost::thread::hardware_concurrency() << endl; //输出CPU核心数
boost::this_thread::yield(); //放弃当前CPU时间

 c++11中也有对应的操作,eg:

std::this_thread::sleep_for(std::chrono::seconds()); //睡眠5秒
std::this_thread::sleep_for(4ms); //睡眠4毫秒,需要引用命名空间:using namespace std::chrono

 3、线程中断

thread的成员函数interrupt()设置正在执行的线程被中断,被中断的线程会抛出一个thread_interrupted异常,它不是std::exception或boost::exception的子类。thread_interrupted异常应该在线程执行函数里捕获并处理,如下所示,如果没有捕获处理这个异常,默认的动作是终止线程。

void ThreadFun()
try
{
//函数体
}
catch (boost::thread_interrupted&)
{
//异常处理
}

线程其实不是任意时刻都能被中断的,只有当线程执行到中断点的时候才被中断,thread中的中断点有:thread::join()系列函数、thread::sleep()函数、condition_variable::wait()系列函数、this_thread::interruption_point()函数,其中this_thread::interruption_point()函数表示执行到本函数的时候就可以被中断。

缺省情况下线程都是允许中断的,this_thread::interruption_enabled()函数可以检测当前线程是否允许中断,this_thread::interruption_requested()用来检测当前线程是否被要求中断。this_thread中的disable_interruption类是一个RAII类型的对象,它在构造的时候关闭线程的中断,析构的时候恢复线程的中断状态。

 4、线程组

线程组thread_group用于管理一组创建的线程,成员函数create_thread()可以创建thread对象并运行线程,也可以创建thread对象后使用成员函数add_thread()来加入线程组。成员函数create_thread()的声明如下:

template<typename F>
thread* create_thread(F threadfunc);

成员函数remove_thread()可以删除线程组里的thread对象,成员函数join_all()用来等待所有的thread对象,成员函数interrupt_all()用来中断所有的thread对象。

使用示例:

    boost::thread_group tg;

    int n1 = ;
tg.create_thread(bind(ThreadFun1, n1, "c++"));
int n2 = ;
tg.create_thread(bind(ThreadFun2, n2, "python")); tg.join_all();

5、future

如果想要获得线程函数的返回值,可以使用future范式。

6、call_once()

call_once()用来设置在多线程环境下指定的函数只被调用一次。

7、C++11中的线程

#include <thread>
void foo(int x)
{
x = ;
} void bar(int& x)
{
x = ;
} int main()
{
int n1 = , n2 = ;
std::thread first(foo, n1);
std::thread second(bar, ref(n2)); first.join(); //first.detach();
second.join(); //second.detach(); cout << n1 << endl; //n1为50
cout << n2 << endl; //n2为0 return ;
}

需要注意的几点:

①、可执行的thread对象必须在他被销毁之前被主线程join(调用thread对象的join())或者将其设置为 detached(调用thread对象的detach),否则会产生abort。

②、如果使用函数对象作为thread的参数的话,直接传入临时对象会出错,可以定义一个对象传入或者使用lambda表达式:

class CTask
{
public:
void operator()()
{
int a = ;
}
}; //std::thread th1(CTask()); //直接传入临时对象会出错
CTask task;
std::thread th1(task);
th1.join();

③、传递给线程函数的参数是先保存在于一个中转站中,当函数执行的时候再传给函数的形参,而这个时候传递的参数指向的值很有可能已经失效,所以,对于线程函数传递的参数应该与形参类型相同,而不是再进行转换:

void task(int& a, string str)
{ } int iNum = ;
char* pStr = new char[];
strcpy(pStr, "test");
//std::thread th(task, 5, std::ref(iNum), pStr); //不应该直接传入pStr,防止task中还未对参数str初始化成功pStr已被释放。
std::thread th(task, std::ref(iNum), string(pStr)); //应该传入对应类型
delete[] pStr;
th.join();

④、如果线程函数的参数是引用的话传入时还需要使用ref包住传入的参数,否则也是值传递。

boost--线程的更多相关文章

  1. BOOST 线程完全攻略 - 基础篇

    http://blog.csdn.net/iamnieo/article/details/2908621 2008-09-10 12:48 9202人阅读 评论(3) 收藏 举报 thread多线程l ...

  2. BOOST 线程完全攻略 - 扩展 - 可被关闭的线程类

    本文假设读者已经基本了解boost线程库的使用方法. boost是个开源工程,线程这一块也在不断完善之中,到现在这个阶段,boost::thread仅仅实现了一个完美的技术框架,但是读者在实际使用中会 ...

  3. Boost线程库学习笔记

    一.创建一个线程 创建线程 boost::thread myThread(threadFun); 需要注意的是:参数可以是函数对象或者函数指针.并且这个函数无参数,并返回void类型. 当一个thre ...

  4. BOOST 线程完全攻略

    1 创建线程 首先看看boost::thread的构造函数吧,boost::thread有两个构造函数: (1)thread():构造一个表示当前执行线程的线程对象: (2)explicit thre ...

  5. Boost线程详解

    一.创建一个线程 创建线程 boost::thread myThread(threadFun); 需要注意的是:参数可以是函数对象或者函数指针.并且这个函数无参数,并返回void类型. 当一个thre ...

  6. Boost 线程学习笔记

    Bolg转载自:http://www.cnblogs.com/lvdongjie/p/4447193.html 一: 创建线程 #include <iostream> #include & ...

  7. boost 线程库

    http://www.boost.org/ Boost的安装 step1.从www.boost.org下载boost库 step2 在 tools\build\jam_src目录下 运行build.b ...

  8. 【C/C++】BOOST 线程完全攻略 - 基础篇

    C++多线程开发是一个复杂的事情,mfc下提供了CWinThread类,和AfxBeginThread等等函数,但是在使用中会遇到很多麻烦事情,例如线程之间参数传递的问题,我们一般都是把参数new一个 ...

  9. BOOST 线程完全攻略 - 扩展 - 线程消息通讯

      // controlled_module_ex.hpp : controlled_module类的扩展 // 增强线程之间消息通讯 // 增加线程安全启动和安全关闭功能 // 增加定时器功能 #p ...

  10. BOOST 线程完全攻略 - 结束语

    modulethread扩展多线程破解通讯 全文介绍了3个boost::thread的扩展类,希望能给大家书写多线程代码带来便捷. thread -> controlled_module_ex ...

随机推荐

  1. c#: TabControl隐藏选项卡(WizardPages)

    如Delphi之TPageControl控件,其TTabSheet有TabVisible属性,在制作类似Wizard页面切换时,甚为有用. 而c#对应之TabControl控件,其页面TabPage无 ...

  2. Kylin 与 Spark SQL相比,有哪些差异和优势

    SparkSQL本质上是基于DAG模型的MPP.而Kylin核心是Cube(多维立方体).关于MPP和Cube预处理的差异,重复如下: > MPP [1] 的基本思路是增加机器来并行计算,从而提 ...

  3. Mysql自定义函数functions时报错

    delimiter && [函数创建语句.....] [Err] 1418 - This function has none of DETERMINISTIC, NO SQL, or ...

  4. position的absolute与fixed,absolute与relative共同点与不同点

    absolute与fixed 共同点: (1) 改变行内元素的呈现方式,display被置为block: (2) 让元素脱离普通流,不占据空间: (3) 默认会覆盖到非定位元素上 不同点: absol ...

  5. StackExchange.Redis使用以及封装

    来源:http://www.cnblogs.com/qtqq/p/5951201.html Redis安装:http://www.runoob.com/redis/redis-install.html ...

  6. andorid 数据储存

    .xml <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android ...

  7. redis 数据类型为list命令整理以及示例

    常用来制作队列,当然lpush+rpop也能做栈 #将RPUSH RPUSHX LPUSH LPUSHX一并介绍(具体介绍RPUSH和RPUSHX,因为其实就是插入的方向的区别) RPUSH key ...

  8. 洛谷1288 取数游戏II

    原题链接 因为保证有\(0\)权边,所以整个游戏实际上就是两条链. 很容易发现当先手距离\(0\)权边有奇数条边,那么必胜. 策略为:每次都将边上权值取光,逼迫后手向\(0\)权边靠拢.若此时后手不取 ...

  9. 0 or 1,1 and 0

    最近小编遇到很头疼的的一件事 就是以下这几道运算题 ,以下结果是小编经过大量的运算得出的 一.或运算 1.0 or 1 结果为:1 2.1 or 0 结果为:1 3.1 or 2 结果为:1 4.2 ...

  10. C++动态链接库

    1.动态链接库概述: 动态链接库通常都不能直接运行,也不能接受消息:只有在其他模块调用动态链接库中的函数时,它才发挥作用. Windows API中所有的函数都包含在动态链接库中. 动态链接库分静态库 ...