boost库学习之线程管理

线程管理:
boost::thread类的职责是启动和管理线程对象。大多数时候每个boost::thread实例代表一个独立的线程,boost::thread实例是不可拷贝的。
boost::thread实例是可转移的,因此它们可以被存放到支持转移语义的容器中,由函数返回。这样使得线程对象的创建细节可以用函数包装起来。
boost::thread make_thread();
void f()
{
boost::thread some_thread = make_thread();
some_thread.join();
}
上面这个示例就是说将make_thread实例转移给了 some_thread 因为这段代码后面有一句
注:在支持右值引用的编译器上,boost :: thread提供一个适当的转移构造函数和转移赋值操作,以此来符合C++0x中的可转移拷贝和可转移赋值的概念。在这些编译器的帮助下, boost :: thread能够用于支持转移语义的容器。
对于其他的编译器, 转移语义由一个转移模仿层来支持, 这样容器需要显式检测模仿层。详细资料参考<boost/thread/detail/move.hpp> 我看了一下这个.hpp 里面用的是thread_move_t这个类做了个运算符重载。。

http://www.cnblogs.com/CaiNiaoZJ/archive/2011/08/12/2136598.html这个网址说的运算符重载不错

启动线程1:
通过传递一个拥有无参数构造函数的可调用对象来启动一个线程。这个对象会被拷贝,然后再线程执行的时期调用。如果对象不支持拷贝,可以通过boost::ref传递一个引用,在此种状况下,该对象必须在线程执行期间存在。
struct callable
{
void operator()();
}
boost::thread copies_are_safe()
{
callable x;
return boost::thread(x);
}
返回后,x被销毁,但是新的线程已经拷贝了此对象,所以没问题
boost :: thread oops ()
{
callable x ;
return boost :: thread ( boost :: ref ( x ));
}
返回后,x被销毁,而返回的是引用所以会出现未定义的错。

如果你希望通过带参数的函数或可调用对象来构造一个线程对象,可以通过将额外的参数传递给boost::thread构造函数的方法来实现:
void find_the_question ( int the_answer );
boost :: thread deep_thought_2 ( find_the_question , 42 );参数会被拷贝到线程内部
还有一种办法就是使用bind函数 即boost::thread deep_thought_2(boost::bind(find_the_question,42));
线程标示(IDs)
boost::thread::id对象可用于标示线程。每个执行期的线程都有一个唯一的标示,可通过成员函数get_id()获得,或者在线程内部通过函数boost :: this_thread :: get_id ()获得。boost :: thread :: id 对像支持拷贝, 并提供完整的比较操作符,可以用于关联式容器的键值。尽管没有指定输出格式,线程标识 还是可以以标准操作输出到流。
boost :: thread :: id 对象可能标识线程,也可能没有标识线程(Not-a-Thread)。没有标识线程的对象(Not-a-Thread)在比较时都是相同的,但是和标识了线程的boost :: thread :: id对象都不一样。boost :: thread :: id的比较操作是一致的
下面就是线程类的定义
#include < boost / thread / thread . hpp >
class thread
{
public :
thread ();                                                              //默认构造
~ thread ();
template < class F >
explicit thread ( F f );                                              //带参构造
template < class F , class A1 , class A2 ,.. .>
thread ( F f , A1 a1 , A2 a2 ,...);
template < class F >
thread ( detail :: thread_move_t < F > f );                // move support

thread ( detail :: thread_move_t < thread > x ) ;
thread & operator =( detail :: thread_move_t < thread > x );
operator detail :: thread_move_t < thread >();
detail :: thread_move_t < thread > move ();
void swap ( thread & x ); 
class id ;
id get_id () const ;                                                 //返回线程标识
bool joinable () const ;
void join ();                                                           //join是一个等待子线程结束
bool timed_join ( const system_time & wait_until );
template < typename TimeDuration >
bool timed_join ( TimeDuration const & rel_time );     //调用者等待线程对像执行结束, 或者直到等待的时间结束
void detach (); //线程对象和执行体分离
static unsigned hardware_concurrency ();                  //返回当前系统支持的线程数量
typedef platform - specific - type native_handle_type ;
native_handle_type native_handle (); 
void interrupt ();                                                   //线程中断开启时,在下次进入预定义中断点时或者线程当前在阻塞状态下,线程被中断。
bool interruption_requested () const ;
// backwards compatibility
bool operator ==( const thread & other ) const ;       //比较两个线程是否是同一个线程执行体
bool operator !=( const thread & other ) const ;
static void yield ();                                               //当前线程放弃余下的时间片
static void sleep ( const system_time & xt );           //将调用线程挂起指定的时间
};
void swap ( thread & lhs , thread & rhs );

下面是命名空间this_thread包含的成员
#include <boost/thread/thread.hpp>
namespace this_thread
{
thread::id get_id ();                                    //返回调用线程的线程标识对象

void interruption_point ();                            //检查当前线程是否被中断

bool interruption_requested ();                     //如果当前线程要求中断,返回true否则返回false

bool interruption_enabled ();                       //如果线程中断开启,返回true否则false

template < typename TimeDuration >
void sleep ( TimeDuration const & rel_time );//将调用线程挂起指定的时间

void yield ();                                             //放弃当前线程当前时间片,允许其他线程运行

class disable_interruption
{
public :
disable_interruption ();
~ disable_interruption ();
};                                                              //boost::this_thread::disable_interruption 对象在构造时关闭当前线程中断,在析构后恢复线程中断状态 此对象不支持拷贝和转移。

class restore_interruption
{
public :
explicit restore_interruption ( disable_interruption & disabler );
~ restore_interruption ();
};                                                              //boost::this_thread::restore_interruption 对象的构造将当前线程的中断状态恢复至boost::disable_interruption.当该对象析构时,中断再次关闭。此对象也不支持拷贝和转移。条件是必须和thread::disable_interruption对象在同一个线程创建

template < typename Callable >
void at_thread_exit ( Callable func );             //拷贝func至线程相关存储区。这个拷贝在线程结束时被调用

};

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

第一种用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));
参数可以使函数对象或者指针。当一个thread执行完成时,这个子线程就会消失。注意这个线程对象不会消失,它仍然是一个还处在它的生存期的C++对象。同理,当对一个堆上的线程对象的指针调用delete时候,线程对象被销毁,操作系统的线程并不能保证就消失。
线程组:有两种方法将线程加入线程组
boost::thread_group grp;
boost::thread *p = new boost::thread(threadFun);
这是第一种方法
grp.add_thread(p);
//do something...
grp.remove_thread(p);//将线程组中的p对象从该组移除(不删除该对象)
//这是第二种方法
grp.create_thread(threadFun);
grp.create_thread(threadFun);

grp.join_all();//等待该组内所有的线程结束

中断:
一个执行着的线程可以通过调用对应的boost::thread对象的函数interrupt()来中断,如果一个线程不希望被中断,可以创建一个boost::this_thread::disable_interruption对象来达到这个目的。该对象创建成功后,线程中断关闭,直到该对象被析构:
void f ()
{
// 在此可以中断
{
boost :: this_thread :: disable_interruption di ;
// 不能中断
{
boost :: this_thread :: disable_interruption di2 ;
// 仍然不能中断
} //di2销毁,恢复中断状态
// 在这仍然不能中断
} // di1销毁,恢复中断状态
//现在可以允许中断了
}
};
boost::this_thread::disable_interruption对象关闭的线程中断可以通过构建一个boost::this_thread::reatore_interruption对象来临时打开,

并在构造时传递相应的boost::this_thread::disable_interruption object对象,这样,将恢复线程中断状态到构建boost::this_thread::disable_interruption对象之前,当boost::this_thread::restore_interruption 对像销毁的时候,线程中断会再次处于关闭

void g ()
{
// 此时可以中断
{
boost :: this_thread :: disable_interruption di ;
// 中断被禁止
{
boost :: this_thread :: restore_interruption ri ( di );
// 现在可以中断
} // ri 析构完, 又成为中断禁止状态
} // di对象销毁, 中断状态恢复
// 现在可以进行中断了
}
注:在任何时候,线程中断状态可以通过函数boost :: this_thread :: interruption_enabled ()来取得

预定义的中断点:

下列函数是中断点(interruption points) ,会在被调用线程对像中断开启的情况下抛出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 ()

ok.明天开始学锁。不过明天要先完成项目任务。。现在该下班了~~

 

 

 

 

 

 

posted @ 2013-01-21 20:49  风猴蓝魔  阅读(2855)  评论(0编辑  收藏  举报