Chinaunix首页 | 论坛 | 博客
  • 博客访问: 964789
  • 博文数量: 335
  • 博客积分: 10287
  • 博客等级: 上将
  • 技术积分: 3300
  • 用 户 组: 普通用户
  • 注册时间: 2005-08-08 15:29
文章分类

全部博文(335)

文章存档

2015年(4)

2014年(15)

2013年(17)

2012年(11)

2011年(12)

2010年(96)

2009年(27)

2008年(34)

2007年(43)

2006年(39)

2005年(37)

我的朋友

分类: C/C++

2010-03-10 12:56:42

相关文章:
boost::thread简要分析(1):thread

boost::thread简要分析(2):线程同步

boost::thread简要分析(3):线程局部存储及其它

昨天在写作“大卫的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
#include
#include

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
#include
#include

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
#include
#include
#include

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 中是一样的了。

原文:http://blog.vckbase.com/billdavid/archive/2005/05/19/5566.html

阅读(471) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~