zoukankan      html  css  js  c++  java
  • 管理线程之向线程函数传递參数

    向线程函数传递參数在构造线程对象时就可以完毕。可是要记住,默认情况下是把參数复制到线程内部,即使在函数中使用的是引用。比如

    void f(int i,std::string const &s);
    std::thread t(f,3,"hello");
    上面代码中,函数f的第二个參数是std::string,传递的是char const *会转换为string。

    当使用指针指向自己主动变量时。要特别注意:

    void f(int i, std::string const& s);
    void oops(int some_param)
    {
    	char buffer[1024];
    	sprintf(buffer,"%i",some_param);
    	std::thread t(f,3,buffer);
    	t.detach();
    }
    在这样的情况下,指针指向局部变量buffer,然后传递到新创建的线程。

    非常可能会发生函数oops已经终止。可是buffer还没有转换为std::string。这是buffer已经销毁。解决办法就是在传递之前就转换:

    void f(int i, std::string const& s);
    void oops(int some_param)
    {
    	char buffer[1024];
    	sprintf(buffer,"%i",some_param);
    	std::thread t(f,3,std::string(buffer));
    	t.detach();
    }
    这是,依赖buffer想std::string的隐式转换,之后作为函数參数

    可能会出现和上面相反的情况:线程拷贝了对象实例,可是你想要传递引用。在使用引用传递參数。线程更新数据时:

    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的引用。当线程终止,线程内部的拷贝析构,可是函数process_widget_data传递的是未更新的data。对于熟悉std:bind的人来说,立即就能想到解决的办法:你须要使用std::ref包装參数。须要更改线程创建形式为:

    std::thread t(update_data_for_widget,w,std::ref(data));
    假设你熟悉std::bind,參数传递的语法就easy理解。

    由于std::thread的构造函数和std::bind都是使用相同的原理。这也就是说,你能够传递成员函数的指针作为函数參数,假如你使用对象指针作为第一个參数。

    class X
    {
    	public:
    		void do_lengthy_work();
    };
    X my_x;
    std::thread t(&X::do_length_work,&my_x);
    上面代码会在新线程调用my_x.do_lengthy_work()。由于my_x的地址作为对象指针。你也能够提供參数比如成员函数调用:std::thread的第三个參数将会成为成员函数的第一个參数。

    另一种情况是函数參数对象不能拷贝,仅仅能转移其全部权(比如STL中的auto_ptr指针)。std::unique_ptr就是这种一个样例。std::unique指针一次仅仅能指向一个对象。当指针析构时。对象也就被析构了。在赋值时是转移全部权(像auto_ptr)。

    在使用时,当对象是暂时对象时,会自己主动调用move,当是个变量时必须调用move。

    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));
  • 相关阅读:
    在osg的图形上贴一张纹理图片
    在vs下的osg的qt窗口开发例子以及一些注意事项
    几个排序算法
    UVa11988-破损的键盘 Broken Keyboard
    UVa 442-矩阵链乘 Matrix Chain Multiplication
    Uva 514-铁轨 Rails
    Uva 136-丑数 ugly number
    修改 Sublime 按快捷键 ctrl+s 自动格式化(reindent lines)的问题
    React Native 项目配置 Flow (windows环境)
    Redux-Form 基础使用
  • 原文地址:https://www.cnblogs.com/wzjhoutai/p/7293797.html
Copyright © 2011-2022 走看看