boost::thread简要分析(1):thread

昨天在写作“大卫的Design Patterns学习笔记”过程中,编写了一个多线程Producer -Consumer的示例,其中用到了boost ::thread,但在线程同步的问题上遇到了些问题,到csdn和vckbase上发帖子问了一下,也没人回答,没有办法,只好晚上回家搬出源码研究了一下,总算解决了问题,下面将自己的理解写下来,与大家分享、讨论。
注:以下讨论基于boost1 .32.0

boost ::thread库跟boost ::function等很多其它boost组成库不同,它只是一个跨平台封装库(简单的说,就是根据不同的宏调用不同的API),里面没有太多的GP编程技巧,因此,研究起来比较简单。

boost ::thread库主要由以下部分组成:
thread
mutex
scoped_lock
condition
xtime
barrier
下面依次解析如下:

thread
thread自然是boost ::thread库的主角,但thread类的实现总体上是比较简单的,前面已经说过,thread只是一个跨平台的线程封装库,其中按照所使用的编译选项的不同,分别决定使用Windows线程API还是pthread,或者Macintosh Carbon平台的thread实现。以下只讨论Windows,即使用BOOST_HAS_WINTHREADS的情况。
thread类提供了两种构造函数:
thread ::thread ()
thread ::thread ( const function0 < void >& threadfunc )
第一种构造函数用于调用GetCurrentThread构造一个当前线程的thread对象,第二种则通过传入一个函数或者一个functor来创建一个新的线程。第二种情况下,thread类在其构造函数中间接调用CreateThread来创建线程,并将线程句柄保存到成员变量m_thread中,并执行传入的函数,或执行functor的 operator  ()方法来启动工作线程。
此外,thread类有一个Windows下的程序员可能不大熟悉的成员函数join,线程(通常是主线程)可以通过调用join函数来等待另一线程(通常是工作线程)退出,join的实现也十分简单,是调用WaitForSingleObject来实现的:
WaitForSingleObject ( reinterpret_cast <HANDLE >(m_thread ), INFINITE );
我们可以用以下三种方式启动一个新线程:
1
、传递一个工作函数来构造一个工作线程
#include <boost/thread/thread.hpp>
#include <boost/thread/mutex.hpp>
#include <iostream>

boost ::mutex io_mutex ;

void
 count ()     // worker function
{
    for
 ( int i  =  0 ; i  <  10 ; ++i )
    {

        boost ::mutex ::scoped_lock lock (io_mutex );
        std ::cout  << i  << std ::endl ;
    }
}


int
 main ( int argc ,  char * argv [])
{

    boost ::thread thrd1 (&count );
    boost ::thread thrd2 (&count );
    thrd1 .join ();
    thrd2 .join ();

    return
 0 ;
}

2
、传递一个functor对象来构造一个工作线程
#include <boost/thread/thread.hpp>
#include <boost/thread/mutex.hpp>
#include <iostream>

boost ::mutex io_mutex ;

struct
 count
{

    count ( int id ) : id (id ) { }

    void
 operator ()()
    {

        for
 ( int i  =  0 ; i  <  10 ; ++i )
        {

            boost ::mutex ::scoped_lock lock (io_mutex );         // lock io, will be explained soon.
            std ::cout  << id  <<  ": "  << i  << std ::endl ;
        }
    }


    int
 id ;
};


int
 main ( int argc ,  char * argv [])
{

    boost ::thread thrd1 (count ( 1 ));
    boost ::thread thrd2 (count ( 2 ));
    thrd1 .join ();
    thrd2 .join ();
    return
 0 ;
}

3
、无需将类设计成一个functor,借助bind来构造functor对象以创建工作线程
#include <boost/thread/thread.hpp>
#include <boost/thread/mutex.hpp>
#include <boost/bind.hpp>
#include <iostream>

boost ::mutex io_mutex ;

struct
 count
{

    static
 int num ;
    int
 id ;

    count () : id (num ++) {}

    int
 do_count ( int n )
    {

        for
 ( int i  =  0 ; i  < n ; ++i )
        {

            boost ::mutex ::scoped_lock lock (io_mutex );
            std ::cout  << id  <<  ": "  << i  << std ::endl ;
        }

        return
 id ;
    }
};


int
 count ::num  =  1 ;

int
 main ( int argc ,  char * argv [])
{

    count c1 ;
    boost ::thread thrd1 (boost ::bind (&count ::do_count , &c1 ,  10 ));
    thrd1 .join ();
    return
 0 ;
}

其中bind是一个函数模板,它可以根据后面的实例化参数构造出一个functor来,上面的boost ::bind (&count ::do_count , &c1 ,  10 )其实等价于返回了一个functor:
struct
 countFunctor
{

    int
 operator () ()
    {
        (&
c1 )->do_count ( 10 );     // just a hint, not actual code
    }
};

因此,以后就跟 2中是一样的了。
  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值