• c/c++ 多线程 参数传递


    多线程 参数传递

    1,值传递,拷贝一份新的给新的线程。线程1中有个int变量a,在线程1中启动线程2,参数是a的值,这时就会拷贝a,线程1和线程2不共享a。

    2,引用传递,不拷贝一份新的给新的线程。线程1中有个int变量a,在线程1中启动线程2,参数是a的引用,这时就不会拷贝a,线程1和线程2共享a。※传递参数时,必须明确指出使用std::ref函数,不写std::ref,编译不过。

    3,指针传递,浅拷贝原来的指针给新的线程。线程1中有个指向int变量a的指针,在线程1中启动线程2,参数是a的地址,这时就不会拷贝a,只是浅拷贝指向a的指针,线程1和线程2共享a。

    4,unique_ptr作为参数传递,必须使用move函数

    5,函数的指针作为参数传递

    引用传递,指针传递的注意事项:因为线程2里使用的是线程1的变量a,所以如果线程1比线程2提前结束了,结束的同时就会释放变量a的内存空间,可是这时线程2还没结束,再去访问线程1中的变量a的话,就会发生意想不到的错误!!!

    2,引用传递,例子:

    一共3个线程,main函数是一个线程,在main函数里启动了线程2(f1函数),在线程2(f1函数)里启动了线程3(f2函数)。

    #include <iostream>
    #include <thread>
    #include <string>
    #include <unistd.h>
    
    using namespace std;
    
    void f2(int& i){
      cout << "f2:" << i << endl;
    }
    void f1(int& i){
      cout << "f1:" << i << endl;
      int j = 11;
      thread t(f2, ref(j));//-------------->②
      t.detach();
    }
    int main(){
      int i = 10;
      thread t(f1, ref(i));
      t.detach();//-------------->①
      pthread_exit(NULL);
    }
    

    执行结果:

    f1:10
    f2:0
    

    执行结果分析:

    • 打印出【f1:10】的原因可能是,①处分离线程后,main函数所在的线程还没有结束,所以i还没有被释放掉,所以能打印出10;还有可能是main函数所在的线程虽然已经结束了,但是巧合的是值还是10。
    • 打印出【f2:0】的原因是,②处分离线程后,线程f1已经结束了,所以函数f1里的j已经被释放了,这时线程f2再访问j的时候就是0了。

    3,指针传递,例子:

    一共3个线程,main函数是一个线程,在main函数里启动了线程2(f1函数),在线程2(f1函数)里启动了线程3(f2函数)。

    #include <iostream>
    #include <thread>
    #include <string>
    #include <unistd.h>
    
    using namespace std;
    
    void f2(int* i){
      cout << "f2:" << *i << endl;
    }
    void f1(int& i){
      cout << "f1:" << i << endl;
      int j = 11;
      thread t(f2, &j);
      t.detach();//-------------->②
    }
    int main(){
      int i = 10;
      thread t(f1, ref(i));
      t.detach();//-------------->①
      pthread_exit(NULL);
    }
    
    

    执行结果:

    f1:10
    f2:0
    

    执行结果分析:

    • 打印出【f1:10】的原因可能是,①处分离线程后,main函数所在的线程还没有结束,所以i还没有被释放掉,所以能打印出10;还有可能是main函数所在的线程虽然已经结束了,但是巧合的是值还是10。
    • 打印出【f2:0】的原因是,②处分离线程后,线程f1已经结束了,所以函数f1里的j已经被释放了,这时线程f2再访问j的时候就是0了。

    4,unique_ptr作为参数传递,必须使用move函数

    #include <iostream>
    #include <thread>
    #include <string>
    #include <unistd.h>
    
    using namespace std;
    
    void f1(unique_ptr<int> upt){
      cout << *upt << endl;
    }
    
    int main(){
      unique_ptr<int> upt(new int(10));
      //必须使用move函数,否则编译不过
      thread t(f1, move(upt));
      t.detach();
      pthread_exit(NULL);
    }
    
    

    5,函数的指针作为参数传递

    #include <iostream>
    #include <thread>
    #include <string>
    #include <unistd.h>
    
    using namespace std;
    
    class Test{
    public:
      void func(int& i){
        cout << i << endl;
      }
    };
    int main(){
      Test da;
      int i = 10;
      //&Test::func为对象的方法的指针,&da为对象的指针,ref(i)是方法func的参数
      thread t(&Test::func, &da, ref(i));
      t.detach();
      pthread_exit(NULL);
    }
    
    
    

    c/c++ 学习互助QQ群:877684253

    本人微信:xiaoshitou5854

  • 相关阅读:
    js获取页面传递过来的值
    pdf生成
    行内元素和块级元素有哪些
    Relative 定位与Absolute 定位实例
    rsync全网备份
    nginx1.15.8源码安装
    网页内容抓取工具、利用多线程
    正则表达式获取HTML标记中的内容。(注:如果内容中含有回车符,请查看第三个例子)
    SQL用一个表的数据更新另一个表的数据
    将Winform编译成DLL供C/S程序引用(Winform引用Winform)
  • 原文地址:https://www.cnblogs.com/xiaoshiwang/p/9867091.html
Copyright © 2020-2023  润新知