Boost::thread库的使用

阅读对象

本文假设读者有几下Skills

[1]在C++中至少使用过一种多线程开发库,有Mutex和Lock的概念。

[2]熟悉C++开发,在开发工具中,能够编译、设置boost::thread库。

环境

[1]Visual Studio 2005/2008 with SP1

[2]boost1.39/1.40

 

概要

通过实例介绍boost thread的使用方式,本文主要由线程启动、Interruption机制、线程同步、等待线程退出、Thread Group几个部份组成。

正文

线程启动

线程可以从以下三种方式启动:

第一种用struct结构的operator成员函数启动:

struct callable

{

   void operator()() {  这里略去若干行代码   }

};

 

这里略去若干行代码

 

Callable x;

Boost::thread t(x);

 

第二种以非成员函数形式启动线程

 void  func(int nP)

 {  这里略去若干行代码

}

这里略去若干行代码

Boost::thread  t(func,123);

第三种以成员函数形式启动线程

#include <boost/bind.hpp>

 

这里略去若干行代码

 

class testBind{

public:

  void testFunc(int i)

{

  cout<<”i=”<<i<<endl;

}

};

 

这里略去若干行代码

 

testBind tb;

boost::thread t(boost::bind(&testBind::testFunc,&tb,100));

Interruption机制

可以通过thread对象的interrupt函数,通知线程,需要interrupt。线程运行到interruption point就可以退出。

Interruption机制举例:

#include "stdafx.h"

#include <iostream>

#include <boost/thread.hpp>

using namespace std;

 

void f()

{

     for(int i=1;i<0x0fffffff;i++)

     {

         if(i%0xffffff==0)

         {

              cout<<"i="<<((i&0x0f000000)>>24)<<endl;

             cout<<"boost::this_thread::interruption_requested()="<<boost::this_thread::interruption_requested()<<endl;

              if(((i&0x0f000000)>>24)==5)

              {

                   boost::this_thread::interruption_point();

              }

         }

     }

}

 

int _tmain(int argc, _TCHAR* argv[])

{

     boost::thread t(f);

     t.interrupt();

     t.join();  //等待线程结束

     return 0;

}

 

t.interrupt();告诉t线程,现在需要interrupt。 boost::this_thread::interruption_requested()可以得到当前线程是否有一个interrupt请求。若有 interrupt请求,线程在运行至interruption点时会结束。 boost::this_thread::interruption_point();就是一个interruption point。Interruption point有多种形式,较常用的有 boost::this_thread::sleep(boost::posix_time::seconds(5));当没有interrupt请求 时,这条语句会让当前线程sleep五秒,若有interrupt requirement线程结束。

如何使线程在运行到interruption point的时候,不会结束,可以参考下面的例子:

#include "stdafx.h"

#include <iostream>

#include <boost/thread.hpp>

using namespace std;

 

void f()

{

     for(int i=1;i<0x0fffffff;i++)

     {

         if(i%0xffffff==0)

         {

              cout<<"i="<<((i&0x0f000000)>>24)<<endl;

 

             cout<<"boost::this_thread::interruption_requested()"<<boost::this_thread::interruption_requested()<<endl;

 

              if(((i&0x0f000000)>>24)==5)

              {

                   boost::this_thread::disable_interruption di;

                   {

                       boost::this_thread::interruption_point();

                   }

              }

         }

     }

}

 

int _tmain(int argc, _TCHAR* argv[])

{

     boost::thread t(f);

     t.interrupt();

     t.join();  //等待线程结束

 

     return 0;

}

 

 

注意boost::this_thread::disable_interruption这条语句的使用,它可以使大括号内的interruption point不会中断当前线程。

线程同步

Boost提供了多种lock导致上手需要较长时间,还是看下面线程同步的例子比较简单,相信在多数应用中足够:

 

直接使用boost::mutex的例子

static boost::mutex g_m;

这里略去若干行代码

g_m.lock();

需要锁定的代码

g_m.unlock();

这里略去若干行代码

if(g_m.try_lock())

{

需要锁定的代码

}

这里略去若干行代码

 

 

使用lock guard的例子

#include <iostream>

#include <string>

#include <boost/thread.hpp>

#include <boost/thread/mutex.hpp>

#include <boost/thread/locks.hpp>

 

using namespace std;

 

static boost::mutex g_m;

 

void f(string strName)

{

     for(int i=1;i<0x0fffffff;i++)

     {

         if(i%0xffffff==0)

         {

              boost::lock_guard<boost::mutex> lock(g_m);

              cout<<"Name="<<strName<<" i="<<((i&0x0f000000)>>24)<<endl;

         }

     }

}

 

int _tmain(int argc, _TCHAR* argv[])

{

     boost::thread t(f,string("inuyasha"));

     boost::thread t2(f,string("kagula"));

     boost::thread t3(f,string("kikyou"));

 

     {

         boost::lock_guard<boost::mutex> lock(g_m);

         cout<<"thread id="<<t.get_id()<<endl;

     }

 

     t.join();

     t2.join();

     t3.join();

 

     return 0;

}

 

 

使用unique lock的例子

#include <iostream>

#include <string>

#include <boost/thread.hpp>

#include <boost/thread/mutex.hpp>

#include <boost/thread/locks.hpp>

 

using namespace std;

 

static boost::mutex g_m;

 

void f(string strName)

{

     cout<<"Thread name is "<<strName<<"-----------------begin"<<endl;

     for(int i=1;i<0x0fffffff;i++)

     {

         if(i%0xffffff==0)

         {

              boost::unique_lock<boost::mutex> lock(g_m);

 

              cout<<"Name="<<strName<<" i="<<((i&0x0f000000)>>24)<<endl;

             

              lock.unlock();

         }

     }

     cout<<"Thread name is "<<strName<<"-----------------end"<<endl;

}

 

int _tmain(int argc, _TCHAR* argv[])

{

     boost::thread t(f,string("inuyasha"));

     boost::thread t2(f,string("kagula"));

     boost::thread t3(f,string("kikyou"));

 

     t.join();

     t2.join();

     t3.join();

 

     return 0;

}

同Lock_guard相比

[1]Unique lock中有owns lock成员函数,可判断,当前有没有被lock。

[2]在构造Unique Lock时可以指定boost::defer_lock_t参数推迟锁定,直到Unique Lock实例调用Lock。或采用下面的编码方式使用:

     boost::unique_lock<boost::mutex> lock(mut,boost::defer_lock);

     boost::unique_lock<boost::mutex> lock2(mut2,boost::defer_lock);

     boost::lock(lock,lock2);

[3]它可以和Conditoin_variable配合使用。

[4]提供了try lock功能。

 

 

如果线程之间执行顺序上有依赖关系,直接到boost官网中参考条件变量(Condition variables)的使用。官网关于Conditon Variables的说明还是容易看懂的。

注意,使用一个不恰当的同步可能消耗掉1/2以上的cpu运算能力。

Thread Group

线程组使用示例,其中f函数在上面的例子已经定义

int _tmain(int argc, _TCHAR* argv[])

{

     boost::thread_group tg;

     tg.add_thread(new boost::thread(f,string("inuyasha")));

     tg.add_thread(new boost::thread(f,string("kagula")));

     tg.add_thread(new boost::thread(f,string("kikyou")));

     tg.join_all();

     return 0;

}

参考来源

http://blog.csdn.net/cedricporter/article/details/6909108

[1]www.boost.org

 

 

 

 

Boost.Thread可以使用多线程执行可移植C++代码中的共享数据。它提供了一些类和函数来管理线程本身,还有其它一些为了实现在线程之间同步数据或者提供针对特定单个线程的数据拷贝。
头文件:
#include <boost/thread.hpp>

线程定义
boost::thread 类是负责启动和管理线程。每个boost::thread对象代表一个单独的执行线程,是不可拷贝的。由于它是可以被移动到,所以它们可以被保存到会改变大小的容器中,并且从函数返回。这使得线程创建的详细信息可以被封装到一个函数中。
boost::thread make_thread();

void f()
{
 boost::thread some_thread = make_thread();
 some_thread.join();
}

启动线程
一个新的线程可以通过传递一个可被调用的类型对象来启动,这个对象可以不需要给构造器参数就被唤醒。对象被拷贝到内存,并 且在最新创建的线程上唤醒。如果对象不能被拷贝,boost::ref可以以引用的方式来传递给函数对象。在这种情况下,用户的boost.thread 必须确保对象的引用的生命期必须比最新创建的执行线程要长。

struct callable
{
    void operator()();
};

boost::thread copies_are_safe()
{
    callable x;
    return boost::thread(x);
} // x is destroyed, but the newly-created thread has a copy, so this is OK

boost::thread oops()
{
    callable x;
    return boost::thread(boost::ref(x));
} // x is destroyed, but the newly-created thread still has a reference
  // this leads to undefined behaviour

如果你用一个函数或者可调用的对象希望创建一个boost::thread 的实例需要提供一些参数,这些可以通过给它的构造体传递另外的参数来办到。

void find_the_question(int the_answer);

boost::thread deep_thought_2(find_the_question,42);
参数被拷贝到内部线程结构里:如果需要传递一个引用,可以使用boost::Ref,只是对可调用对象的引用。
没有指定限制传递的额外参数的数量。

线程中的异常
如果传入到boost::thread构造体的函数或者可调用的对象抛出了一个异常而且唤醒它的不是boosst::thread_interrupted类型,std::terminate()会被调用来结束这个线程。

等待
当代表一个执行线程的线程对象被破坏时,这个线程变成分离的,一旦它被分离,将会继续执行知道唤醒由构造体提供的函数或者可调用对象执 行结束,或者程序已经结束。线程也可以通过调用detach()成员函数来显示的分离。在这种情形下,线程对象将不在表示一个当前分离的线程,而是一个非 线程体。
为了等待一个线程执行完毕,必须使用join()和timed_join()成员函数。join()会阻塞调用的线程直到线程结束。如果 线程刚刚执行结束,或者它已经不代表一个线程,join()会立即返回。timed_join()也是类似的,但是调用它如果在指定的时间流逝后线程仍然 没有结束它也会返回。

中断
一个正在运行的线程可以通过调用相应的boost::thread对象的interrupt()成员函数来中断。当被中断的线程在下次 执行一个指定的中断点(或者如果它在同时执行一个的时候被锁)并开启中断时,在被中断的线程中就会抛出一个 boost::thread_interrupted异常。如果没有被捕获,这会导致结束被中断线程的执行。与其他异常一样,栈就会被释放,自动存储期对 象的析构体将会被执行。
如果一个线程需要避免被中断,可以创建一个boost::this_thread::disable_interruption实例。这个类的对象在构造体创建线程的时候禁止了中断,可以在析构体调用之前的任意地方恢复允许中断。
void f()
{
    // interruption enabled here
    {
        boost::this_thread::disable_interruption di;
        // interruption disabled
        {
            boost::this_thread::disable_interruption di2;
            // interruption still disabled
        } // di2 destroyed, interruption state restored
        // interruption still disabled
    } // di destroyed, interruption state restored
    // interruption now enabled
}

通过构造一个boost::this_thread::restore_interruption实例可以临时转换一个 boost::this_thread::disable_interruption实例造成的影响,只要在有问题的地方传递一个 boost::this_thread::disable_interruption对象。这会重新恢复中断状态到当 boost::this_thread_diable_interruption对象被构造时,并且在次禁止中断当 boost::this_thread::restore_interruption对象被破坏时。
void g()
{
    // interruption enabled here
    {
        boost::this_thread::disable_interruption di;
        // interruption disabled
        {
            boost::this_thread::restore_interruption ri(di);
            // interruption now enabled
        } // ri destroyed, interruption disable again
    } // di destroyed, interruption state restored
    // interruption now enabled
}
我们可以通过调用boost::this_thread::interruption_enabled()来查询中断的状态。

预定义的中断点
以下函数当允许中断时可能会抛出boost::thread_interrupted异常。
boost::thread::join()
boost::thread::timed_join()
boost::condition_variable::wait()
boost::condition_variable::timed_wait()
boost::condition_variable_any::wait()
boost::condition_variable_any::timed_wait()
boost::thread::sleep()
boost::this_thread::sleep()
boost::this_thread::interruption_point()

线程ID
boost::thread::id类可以用来标识一个线程。每个运行的执行线程都有一个特有的ID,可以通过对应的boost::thread的get_id()成员函数来获得ID。

时间: 2024-08-22 06:55:42

Boost::thread库的使用的相关文章

Boost Thread学习笔记二

除了thread,boost::thread另一个重要组成部分是mutex,以及工作在mutex上的boost::mutex::scoped_lock.condition和barrier,这些都是为实现线程同步提供的. mutexboost提供的mutex有6种:boost::mutexboost::try_mutexboost::timed_mutexboost::recursive_mutexboost::recursive_try_mutexboost::recursive_timed_m

Boost Thread学习笔记五

多线程编程中还有一个重要的概念:Thread Local Store(TLS,线程局部存储),在boost中,TLS也被称作TSS,Thread Specific Storage.boost::thread库为我们提供了一个接口简单的TLS的面向对象的封装,以下是tss类的接口定义: class tss{public:    tss(boost::function1<void, void*>* pcleanup);    void* get() const;    void set(void*

boost::thread用法

最近在做一个消息中间件里面涉及到多线程编程,由于跨平台的原因我采用了boost线程库.在创建线程时遇到了几种线程创建方式现总结如下:     首先看看boost::thread的构造函数吧,boost::thread有两个构造函数: (1)thread():构造一个表示当前执行线程的线程对象: (2)explicit thread(const boost::function0<void>& threadfunc):      boost::function0<void>可以

boost::thread类

前言 标准C++线程即将到来.预言它将衍生自Boost线程库,现在让我们探索一下Boost线程库. 几年前,用多线程执行程序还是一件非比寻常的事.然而今天互联网应用服务程序普遍使用多线程来提高与多客户链接时的效率:为了达到最大的吞吐量,事务服务器在单独的线程上运行服务程序:GUI应用程序将那些费时,复杂的处理以线程的形式单独运行,以此来保证用户界面能够及时响应用户的操作.这样使用多线程的例子还有很多. 但是C++标准并没有涉及到多线程,这让程序员们开始怀疑是否可能写出多线程的C++程序.尽管不可

Boost.Context库简介及协程的构建

最近从各大公司的开源项目看来,基于协程的高性能服务端开发变得越来越流行了,比如我了解到的微信团队的libco.魅族的libgo.以及libcopp.传统的高性能服务端的开发大多都是基于异步框架和多线程或者多进程的模型来设计的,这种架构虽然经历了长久的考验且经验丰富,但是却有着固有的缺点: (1). 异步构架将代码逻辑强行分开,不利于人类常理的顺序思维习惯,自然也不是对开发者友好的: (2). 线程虽然相对于进程共享了大量的数据,创建和切换效率较高,算是作为内核级别轻量级别的调度单元,在X86构架

windows ndk 编译 boost网络库

问题描述 windows ndk 编译 boost网络库 求指教,小弟,不会弄那个路径,不知道咋配置BOOST路径就指教 解决方案 参考:http://blog.csdn.net/ly131420/article/details/46648125 解决方案二: 在windows下编译boost库如何在WINDOWS下编译BOOST C++库ndk 编译 boost 库

linux 下使用boost serialization库,编译问题

问题描述 linux 下使用boost serialization库,编译问题 在linux下使用boost serialization,结果编译不过,折腾了半天也过不去,求大神指导 代码如下,也是网上找的, #include "boost/serialization/serialization.hpp" #include "boost/archive/binary_oarchive.hpp" #include "boost/archive/binary_

如何在WINDOWS下编译BOOST C++库 .

如何在WINDOWS下编译BOOST C++库 cheungmine 2008-6-25   写出来,怕自己以后忘记了,也为初学者参考.使用VC8.0和boost1.35.0.   1)下载boost http://www.boost.org/users/download/ 这是它的下载页面,需要下载2个东西: Packaged Releases VERSION 1.35.0 和 Boost Jam 3.1.16   你需要在每个条目下面找到Details | Download字样,点击Down

boost::thread之while(true)型线程终结方法

我们的程序中经常会用到线程来执行某些异步操作,而有些时候我们的线程执行的函数是这个样子的:   [cpp] view plaincopyprint?   void ThreadBody()   {       while( true )       {           std::cout << "Processing..." << std::endl;           Sleep(1000);       }   }           那么,从理论上讲