管理线程之创建线程
基本的线程管理包括:1、创建线程。2、等待它结束或在后台运行。3、向线程函数传递参数,更改线程对象所有权。4、选择线程和使用特定线程。
创建线程
void do_some_work(); std::thread my_thread(do_some_work);</span>这是最简单的情况,std::thread还可以使用可调用类型(callable type),可以在创建线程对象时,在调用函数处传递一个对象的实例。
class background_task { public: void operator()()const { do_something(); do_something_else(); } }; background_task f; std::thread my_thread(f);在这种情况下,函数对象在新创建线程时被拷贝到新建线程的内存中,并在这开始调用。必须确保拷贝行为等同于原始对象,否则得不到预期的结果。
std::thread my_thread(background_task());声明了一个函数my_thread,这个函数有一个参数(指向函数的指针,返回background_task对象),返回一个std::thread对象,而不是创建新线程。这时可以通过3种方法来避免:1像上面那样命名函数对象。2使用额外的圆括号。3、使用新的标准初始化语法。
std::thread my_thread((background_task()));加上额外的圆括号后,会阻止编译器把它解释成函数的声明,这样就能把my_thread解释成定义std::thread类型对象了。
std::thread my_thread{ background_task() };使用新的标准初始化语法,用花括号而不是圆括号。
std::thread my_thread([]( do_something(); do_something_else(); });
struct func { int &i; func(int &i_)i:(i_){} void operator()() { for(unsigned j=0; j <= 1000000; ++j) { do_something(i); } } }; void oops() { int some_local_state=0; func my_func(some_local_state); std::thread my_thread(my_func); my_thread.detach(); }在这个例子中,新线程在oops函数终止后可能还会运行(分离了新线程),如果线程还在运行,那么函数do_something(i)会使用已经销毁的变量。
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。