赞
踩
我们知道C++11新增了std::thread类来实现线程。
线程的构造很简单。std::thread th1(函数名或者lamda表达式)。 线程构造出来执行函数再退出。
一些简单的成员函数
get_id:获取线程ID,返回一个类型为std::thread::id的对象。
joinable:检查线程是否可被join。检查thread对象是否标识一个活动(active)的可行性线程。缺省构造的thread对象、已经完成join的thread对象、已经detach的thread对象都不是joinable。
join:调用该函数会阻塞当前线程。阻塞调用者(caller)所在的线程直至被join的std::thread对象标识的线程执行结束。比如防止main()主线程在th1完成之前就退出了。
detach:将当前线程对象所代表的执行实例与该线程对象分离,使得线程的执行可以单独进行。一旦线程执行完毕,它所分配的资源将会被释放。
(detach会使线程对象th1失去对该线程的控制权,有可能导致主程序退出时该线程还没执行完,所以一般不用detach,除非它是很重要的后台线程)
hardware_concurrency:静态成员函数,返回当前计算机最大的硬件并发线程数目。基本上可以视为处理器的核心数目。
如果打算等待对应线程,则需要细心挑选调用join()的位置。当在线程运行之后产生异常,在join()调用之前抛出,就意味着很这次调用会被跳过。
向线程函数传递参数
向std::thread构造函数中的可调用对象,或函数传递一个参数很简单,默认参数要拷贝到线程独立内存中,即使参数是引用的形式。
有几种特殊情况需要注意:
线程函数期望传递一个引用,但整个对象被复制过来了。这种情况下传递给函数的参数是data变量内部拷贝的引用,而非数据的本身。所以当线程结束时,内部拷贝数据将会在数据更新阶段被销毁。为了避免这种情况,可以使用std::ref来将参数转换成引用的形式,从而data变量的引用而非data变量拷贝的引用传递过去。
将某个类的成员函数设为线程函数,应传入一个函数指针,指向该成员函数,还需要给出对象指针,作为该函数的第一个参数:
class X {
public:
void do_lengthy_work();
};
X my_x;
std::thread t(&X::do_lengthy_work, &my_x);
转移线程所有权
void some_function();
void some_other_function();
std::thread t1(some_function); // 1
std::thread t2=std::move(t1); // 2
std::thread f() //说明thread可以作为函数的返回值
{
void some_function();
return std::thread(some_function);
}
std::thread g()
{
void some_other_function(int);
std::thread t(some_other_function,42);
return t;
}
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。