zoukankan      html  css  js  c++  java
  • c++线程传参问题

    std::thread可以和任何可调用类型一起工作,可调用对象和函数带有参数时,可以简单地将参数传递给std::thread的构造函数

    例如:

     1 #include<iostream>
     2 #include<thread>
     3 using namespace std;
     4 void hello(int a)
     5 {
     6 cout<<a<<endl;
     7 }
     8 
     9 int mian()
    10 {
    11 int a=10;
    12 thread t(hello,a);
    13 t.join();
    14 }

    单重要的是,参数会以默认的方式复制到内存空间,即内存中存储的是参数的副本,在那里新创建的线程可以访问他们,而不是访问源参数

    这就会带来一个问题,即当调用的函数参数为引用类型时,参数的值在函数体内改变时,希望源数据的值也发生改变,但实际情况是源数据值并不会发生。因为将data传递给线程的构造函数时,线程访问的是其在内存中的副本copydata,传递到可调用函数中的也是对这个副本的引用&copydata,那么函数体内对实参的改变也只是对内存中的副本进行了改变,而data并没有发生改变。当线程完成时,随着所提供参数副本的销毁,这些改变都将舍弃。

    例如:

     1 #incldue<iostream>
     2 #include<thread>
     3 using namespace std;
     4 void hello(int &a)
     5 {
     6 a+=1;
     7 }
     8 
     9 int main()
    10 {
    11 int a=10;
    12 thread t(hello,a);
    13 t.join();
    14 cout<<a<<endl;               //结果为10,而不是11
    15 }

    解决方法:用std::ref来包装引用类型的参数

    #incldue<iostream>
     2 #include<thread>
     3 using namespace std;
     4 void hello(int &a)
     5 {
     6 a+=1;
     7 }
     8 
     9 int main()
    10 {
    11 int a=10;
    12 thread t(hello,ref(a));
    13 t.join();
    14 cout<<a<<endl;               //结果为11
    15 }
  • 相关阅读:
    BZOJ5057 : 区间k小值5
    Urozero Autumn 2016. UKIEPC 2016
    BZOJ2808 : 那些年我们画格子
    BZOJ4970 : [ioi2004]empodia 障碍段
    XVII Open Cup named after E.V. Pankratiev. XXI Ural Championship
    BZOJ4316 : 小C的独立集
    网络流(3)——找到最小st-剪切
    网络流(2)——用Ford-Fullkerson算法寻找最大流
    网络流(1)——网络、流网络和网络流
    退而求其次(4)——椭圆中的最大矩形
  • 原文地址:https://www.cnblogs.com/mrlsx/p/5512222.html
Copyright © 2011-2022 走看看