zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    关于JSON可能出现的错误,待更/todo
    mongoose的安装与使用(书签记录) 2017
    HTTP的学习记录3--HTTPS和HTTP
    HTTP的学习记录(二)头部
    HTTP(一)概述
    LeetCode 455. Assign Cookies
    LeetCode 453. Minimum Moves to Equal Array Elements
    LeetCode 448. Find All Numbers Disappeared in an Array
    LeetCode 447. Number of Boomerangs
    LeetCode 416. Partition Equal Subset Sum
  • 原文地址:https://www.cnblogs.com/xiaoshiwang/p/9867091.html
Copyright © 2011-2022 走看看