zoukankan      html  css  js  c++  java
  • C++线程传参的几个误区

    #include <iostream>
    #include<thread>
    
    using namespace std;
    
    void ThreadFun(const int &arr1,char *pBuf)
    {
        cout << arr1 << endl;
        cout << pBuf << endl;
        return;
    }
    
    int main()
    {
        int temp = 10;
        char arr[20] = "Hello Word";
        std::thread t1(ThreadFun, temp,arr);
        t1.detach();
        std::cout << "主线程运行
    ";
    }

    以上代码有2个误区,

    误区1:大家会认为线程函数第一个参数是引用,线程用的是detach(),则会出现一种问题,就是当主线程退出时,temp变量释放掉了,子线程的第一个参数是引用,所以地址也被释放掉了,而线程函数里面还用到了这个参数,就会出现用了已经释放的地址的问题,这种想法是错的。

    解释:线程函数第一个参数使用的是引用(&arr1),但是实际调试时,它与调用时传进来的实参(temp)的地址不同,则表示它线程函数第一个参数不是实际的引用,是假的引用,只是做了个值的拷贝,所以不会出现用了已经释放的地址的问题。

    线程函数第二个参数是指针,调试时发现地址实参和形参的地址相同,则指传参是有问题的,会出现用了已经释放的地址的问题,不建议使用指针。

    误区2:大家会认为第二个参数不让使用指针,但是我也传字符串那我可以这样写,

    #include <iostream>
    #include<thread>
    
    using namespace std;
    
    void ThreadFun(const int &arr1,string &pBuf)
    {
        cout << arr1 << endl;
        cout << pBuf.c_str() << endl;
        return;
    }
    
    int main()
    {
        int temp = 10;
        char arr[20] = "Hello Word";
        std::thread t1(ThreadFun, temp,arr);
        t1.join();
        std::cout << "主线程运行
    ";
    }

    以上的写法形参和实参的地址不同,看起来没啥问题,但是实际也是错误的,这样写会出现一个问题,就是从代码上看线程函数开始前arr实参是被隐式转换为了string,

    但是程序不确定啥时去转换,调试时有这种可能,就是主线程都退出了,arr还没有被转换为string,此时,主线程退出,arry被释放掉了,现在要把现在就相当与把一块不确定的地址转换为string,这是不对的。正确的使用方法,就是在传参的时候把arr强制转换为临时的string类型传递给线程就不会出现上面的问题。例如: 

    std::thread t1(ThreadFun, temp,string(arr));
    111
  • 相关阅读:
    C programming course
    关于时间管理的培训心得
    吴老师,一路好走!
    自己实现Int32Collection(.Net 1.1),以及效率问题的体会
    《C陷阱与缺陷》和《C专家编程》两本书又翻印了
    暂时闲一会,写一点点面试体会吧
    人类没有一件事是值得烦恼的
    EP0N系统中简便可行的光纤保护方法
    越来越不想写代码了
    [转]PON关键技术-通用成帧协议研究
  • 原文地址:https://www.cnblogs.com/zwj-199306231519/p/13532405.html
Copyright © 2011-2022 走看看