2008-5-23TuYongceyongce@126.comV1.01/391.Thread(译注:本中文文档对应于Boost1.35.0的英文文档。原英文文档版权归AnthonyWilliams所有,本中文文档版权归TuYongceyongce@126.com所有。)概述自Boost1.34以来的变化线程管理同步线程局部存储感谢翻译术语表1.1.概述Boost.Thread使我们能够用可移植的C++代码来使用有共享数据的多个执行线程。它提供了类和函数来管理线程本身,以及在线程间同步数据或者为每一个线程提供单独的数据拷贝。Boost.Thread库昀初由WilliamE.Kempf设计和实现。本版本进行了大量重写以紧密跟进C++标准委员会发布的建议,特别是N2497、N2320、N2184、N2139和N2094。1.2.自Boost1.34以来的变化自Boost1.34发行版以来,几乎Boost.Thread的每一行代码都发生了变化(译注:Boost.Thread昀初发行版出现于Boost1.25.0)。然而,大多数接口变化被扩展了,因此新代码很大程度上向后兼容于旧有代码。新的特性和breaking变化描述如下。新特性zboost::thread实例和各种锁类型现在是可移动的。z线程可以在中断点被中断。z条件变量现在能够用于任何实现了Lockable概型的类型,通过使用boost::condition_variable_any(boost::condition是boost::condition_variable_any的类型别名,以向后兼容)。boost::condition_variable被提供作为优化,并只与boost::unique_lockboost::mutex(boost::mutex::scoped_lock)一块工作。z线程ID从boost::thread中分离出来,因此一个线程可以获得它自己的ID(使用boost::this_thread::get_id()),并且这些ID可以用作关联容器的键值,因为它们有比较操作符的全部集合。z超时设定现在使用Boost.Date_Time库实现,通过类型别名boost::system_time提供的绝对超时设定,并支持许多情形下的相对超时。boost::xtime被支持以向后兼容。z锁被实现为公共可访问的模板boost::lock_guard、boost::unique_lock、boost::shared_lock和boost::upgrade_lock,它们在互斥类型基础上模板化。Lockable概型被扩展包含公共可用的2008-5-23TuYongceyongce@126.comV1.02/39lock()和unlock()成员函数,它们被锁类型使用。breaking变化下面的列表应该覆盖了所有打破向后兼容的公共接口变化。zboost::try_mutex已经被移除,其功能包含在boost::mutex中。boost::try_mutex作为一个类型别名,但不再是一个单独的类。zboost::recursive_try_mutex已经被移除,其功能包含在boost::recursive_mutex中。boost::recursive_try_mutex作为一个类型别名,但不再是一个单独的类。zboost::detail::thread::lock_ops已经被移除。依赖于lock_ops实现细节的代码将再工作,因为这已经被移除,事实上不再需要,因为互斥类型现在已经提供了公共的lock()和unlock()成员函数。z拥有第二个类型为bool的参数的scoped_lock构造函数不再提供。在先前的版本中,boost::mutex::scoped_locksome_lock(some_mutex,false);能够被用于创建一个与一个互斥对象关联的锁对象,但是在构造时不会锁定。现在通过采用boost::defer_lock_type作为第二个参数的构造函数来代替该功能:boost::mutex::scoped_locksome_lock(some_mutex,boost::defer_lock);zboost::read_write_mutex已经被boost::shared_mutex代替。1.3.线程管理概要类thread名字空间this_thread类thread_group1.3.1.概要boost::thread类负责启动和管理线程。每个boost::thread对象代表一个单独的执行线程或者Not-a-Thread,至多一个boost::thread对象代表一个给定的执行线程:boost::thread类型的对象是不可复制的。然而,boost::thread类型的对象是可移动的(movable),因此它们能够被存储在move-aware容器中,也可由函数返回。这允许线程创建细节被封装在一个函数中。例如:boost::threadmake_thread();voidf(){boost::threadsome_thread=make_thread();some_thread.join();}启动线程2008-5-23TuYongceyongce@126.comV1.03/39通过传递一个可调用类型的对象给构造函数来启动一个新的线程,传递的对象必须能够进行无参调用。该对象随后被复制到内部存储中,并在新创建的执行线程中调用。如果该对象禁止(或者不能)复制,那么可以使用boost::ref来传递函数对象的引用。在这种情况下,Boost.Thread的用户必须确保被引用的对象比新创建的执行线程的生命期更长。例如:structcallable{voidoperator()();};boost::threadcopies_are_safe(){callablex;returnboost::thread(x);}//x被销毁,但是新创建的线程有一份拷贝,因此没有问题boost::threadoops(){callablex;returnboost::thread(boost::ref(x));}//x被销毁,但新创建的线程仍然拥有一个对它的引用,将导致未定义行为如果你想使用一个需要参数的函数或者可调用对象来构造一个boost::thread的实例,这可以通过boost::bind来实现。例如:voidfind_the_question(intthe_answer);boost::threaddeep_thought_2(boost::bind(find_the_question,42));汇合与分离(Joining&Detaching)当代表一个执行线程的boost::thread对象被销毁时,线程变为分离的(detached)。一旦一个线程是分离的,它将继续执行直到该函数或者可调用对象的调用完成或者程序终止。线程也可以通过显式地对boost::thread对象调用detach()成员函数来分离。这种情况下,boost::thread对象不再代表一个已分离线程,而代表Not-a-Thread。为了等待一个执行线程结束,必须使用boost::thread对象的join()或者timed_join()成员函数。join()将阻塞调用线程,直到boost::thread对象代表的线程结束。如果boost::thread对象代表的执行线程已经结束,或者boost::thread对象代表Not-a-Thread,那么join()立即返回。timed_join()是类似的,除了一点:在指定时间内被等待线程仍然没有结束,timed_join()调用也将返回。中断可以通过调用对应的boost::thread对象的interrupt()成员函数来中断一个正在运行的线程。在中断启用下,当一个被中断的线程接下来执行某一指定中断点时(或者如果它当前正被阻塞,并且正在执行一个中断点),那么该被中断线程将抛出一个boost::thread_interrupted异常。如果未被捕获,将引起被中断线程的执行终止。和其它任何异常一样,栈将被展开(unwind),对象析构函数将被调用。如果线程想避免被中断,它可以创建一个boost::this_thread::disable_interruption的实例。该类对2008-5-23TuYongceyongce@126.comV1.04/39象在构造后对创建它的线程禁用中断,并在析构后恢复中断状态到禁用之前的状态。例如:voidf(){//这里中断被启用{boost::this_thread::disable_interruptiondi;//中断被禁用{boost::this_thread::disable_interruptiondi2;//中断仍被禁用}//di2被销毁,中断状态被恢复//中断仍被禁用}//di被销毁,中断状态被恢复//现在中断被启用}boost::this_thread::disable_interruption实例的影响可以通过构造一个boost::this_thread::restore_interruption实例来临时撤消,并传入该boost::this_thread::disable_interruption对象。这将恢复中断状态到该boost::this_thread::disable_interruption对象被构造之前的状态。当该boost::this_thread::restore_interruption对象被销毁时,再次禁用中断。例如:voidg(){//这里中断被启用{boost::this_thread::disable_interruptiondi;//中断被禁用{boost::this_thread::restore_interruptionri(di);//现在启用中断}//ri被销毁,再次禁用中断}//di被销毁,中断状态被恢复//现在中断被启用}在任何时刻,可以通过调用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()2008-5-23TuYongceyongce@126.comV1.05/39boost::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()成员函数获得,或者通过在线程内调用boost::this_thread::get_id()获得。类boost::thread::id的对象可以复制,可以用作关联容器的键值:提供了所有的比较操作符。也可以使用流插入操作符把线程ID写到输出流中,虽然其输出格式未指定。每一个boost::thread::id的实例要么引向某个线程,要么引向Not-a-Thread。在比较时,引向Not-a-Thread的实例都是相等的,但不等于任何一个引向实际执行线程的实例。boost::thread::id上的比较操作符为每一个不相等的