标签:c++11 并发 concurrency 参数
我们可以通过std::thread的构造函数向线程传递参数,但是默认情况下,这些参数的拷贝会被传递到线程内部,即使参数申明为引用,也是如此:
void f(int i,std::string const& s); std::thread t(f,3,"hello");如上面例子所示,创建了一个线程关联到t,它会调用f(3, "hello"),虽然f的第二个参数类型为std::string,但是实际上字面量hello还是以char const *类型传递到线程内部,再在新的线程上下文内被转换回std::string。
void f(int i,std::string const& s); void not_oops(int some_param) { char buffer[1024]; sprintf(buffer,"%i",some_param); std::thread t(f,3,std::string(buffer)); t.detach(); }另一种情况是我们希望将一个结构实例的引用传递给一个线程,新的线程在其执行过程中更新和修改这个结构:
void update_data_for_widget(widget_id w,widget_data& data); void oops_again(widget_id w) { widget_data data; std::thread t(update_data_for_widget,w,data); display_status(); t.join(); process_widget_data(data); }update_data_for_widget期望第二个参数以引用的方式传递给新的线程,但是std::thread的构造函数并不知道这个需求,它只是将这个结构拷贝一份,传递给新的线程。当update_data_for_widget执行时,它会将拷贝的引用传递给自己,而不是外部的那个data实例的引用,这就导致,线程执行结束,只是修改了data的拷贝,而data本身则没有任何变化。
std::thread t(update_data_for_widget,w, std::ref(data) );还有一种情况是,有些参数不能被拷贝但是可以被移动(move),对象中的数据被转移给另一个对象,之前对象中的数据将被清空。比如,std::unique_ptr,这个类型用于管理动态分配的对象。在同一时刻,只有一个std::unique_ptr的实例可以指向一个特定的对象,当指针被销毁时,其所指向的对象也将被销毁。move构造函数和move赋值运算符使得我们可以在std::unique_ptr实例之间传递对象的所有权。
void process_big_object(std::unique_ptr<big_object>); std::unique_ptr<big_object> p(new big_object); p->prepare_data(42); std::thread t(process_big_object,std::move(p));std::thread构造函数中调用std::move(p)使得big_objects的所有权被传递给新创建线程的内部,然后被传递给process_big_object方法。
可移动(movable)但是不可拷贝(copyable)使得我们可以保证,同一时刻,只有一个对象与一个特定的线程关联,而我们可以在对象之间传递线程的所有权。
版权声明:本文为博主原创文章,未经博主允许不得转载。
标签:c++11 并发 concurrency 参数
原文地址:http://blog.csdn.net/yamingwu/article/details/47341535