thread 类是 thread 库的核心类,负责启动和管理线程对象,在概念上和操作上都与POSIX线程很相似,因此如果对于POSIX线程熟悉的使用者来说,就比较熟悉。这里我们对于类 thread 的分析就以例子来做分析。
下面的测试用例展示了 boost::thread 的最简单的使用场景:也就是创建某个线程,然后等待线程结束,程序终止。
/*********************************************************************************
*Copyright(C),Your Company
*FileName: main.cpp
*Author: Huangjh
*Version:
*Date: 2018-02-11
*Description: boost::thread 的demo1
*Others:
**********************************************************************************/
#include
#include
#include
using namespace std;
using namespace boost;
void wait(int iSeconds)
{
this_thread::sleep(posix_time::seconds(iSeconds));
}
void threadFunction(void)
{
for (int i = 0; i < 5; i++)
{
wait(1);
cout << "threadFunction runnin time : " << i << endl;
}
}
int main(void)
{
cout << "boost thread test start ..." << endl;
thread myThread(threadFunction);
myThread.join();
wait(10);
return 0;
}
运行结果如下所示:
boost thread test start ...
threadFunction runnin time : 0
threadFunction runnin time : 1
threadFunction runnin time : 2
threadFunction runnin time : 3
threadFunction runnin time : 4
在上面的测试用例中,我们简单的创建了一个 thread 对象,在构造这个对象时候我们传入了某个函数指针。我们这边就简单的分析下 thread 对象的构造函数。
template <
class F
>
explicit thread(BOOST_THREAD_RV_REF(F) f
//, typename disable_if::type, thread>, dummy* >::type=0
):
thread_info(make_thread_info(thread_detail::decay_copy(boost::forward(f))))
{
start_thread();
}
对于这个构造函数,我们需要先分析下BOOST_THREAD_RV_REF(F) f 的含义:
#define BOOST_THREAD_RV_REF(TYPE) BOOST_RV_REF(TYPE)
//!This macro is used to achieve portable syntax in move
//!constructors and assignments for classes marked as
//!BOOST_COPYABLE_AND_MOVABLE or BOOST_MOVABLE_BUT_NOT_COPYABLE
#define BOOST_RV_REF(TYPE)\
TYPE && \
这里就涉及到一个概念:引用的折叠—— 一般来讲,我们不能定义一个引用的引用,但是通过类型别名或者模板参数可以间接定义。引用折叠是std::move、std::forward等的工作基础。如果对引用折叠有兴趣的朋友可以自行搜索下,这边就不多做说明。不过需要补充的是:引用折叠是服务于std::move、std::forward等的,而并不是服务于程序员的。只有在少数的情况下,程序员确实需要使用引用折叠来完成一些代码的设计。
接着看这个构造函数的实现,boost::forward 是有条件的转换为右值引用。thread_info(make_thread_info(thread_detail::decay_copy(boost::forward
detail::thread_data_ptr thread_info;
typedef boost::intrusive_ptr thread_data_ptr;
成员变量 thread_info 的类型为 detail::thread_data_ptr。是用于保存线程的数据用的。
成员函数 start_thread()则启动线程。
成员函数join() 是一个阻塞调用:它可以暂停当前线程,直到 join() 的线程运行结束(其实和POSIX的join系统调用类似)。
下面我们通过另外一个测试用例来说明如何通过所谓的中断点让一个线程中断。
/*********************************************************************************
*Copyright(C),Your Company
*FileName: main.cpp
*Author: Huangjh
*Version:
*Date: 2018-02-11
*Description: boost::thread 的demo2
*Others:
**********************************************************************************/
#include
#include
#include
using namespace std;
using namespace boost;
void wait(int iSeconds)
{
this_thread::sleep(posix_time::seconds(iSeconds));
}
void threadFunction(void)
{
try
{
for (int i = 0; i < 5; i++)
{
wait(1);
cout << "threadFunction runnin time : " << i << endl;
}
}
catch (thread_interrupted &)
{
cout << "threadFunction interrupted ..." << endl;
}
}
int main(void)
{
cout << "boost thread test start ..." << endl;
thread myThread(threadFunction);
wait(3);
myThread.interrupt();
myThread.join();
return 0;
}
运行结果如下所示:
boost thread test start ...
threadFunction runnin time : 0
threadFunction runnin time : 1
threadFunction interrupted ...
在一个线程对象上调用interript() 会中断相应的线程。在这方面,中断意味着一个类型为 boost::thread_interrupted 的异常,它会在这个线程中抛出。