WHCSRL 技术网

关于c++11多线程thread类对象作为参数传递,拷贝构造次数问题

thread在使用类对象作为参数传递过程中,常常会出现多次拷贝构造的情况,理想中的情况是只需一次拷贝构造。原因是由于不同编译器对thread函数处理是不同的。

测试代码

#include <iostream>
#include <unistd.h>
#include <thread>
using namespace  std;


/**
 * 用类对象创建线程
 */
class SonTheardClass{
public:
    SonTheardClass(int i):num(i)
    {
        cout <<"构造函数被执行,线程ID:"<<this_thread::get_id()<<endl;
    }
    SonTheardClass(const SonTheardClass &mysonthread):num(mysonthread.num)
    {
        cout<<"拷贝构造被执行,线程ID:"<<this_thread::get_id()<<endl;
    }
    void operator() ()//不能带参数
    {
        cout<<"mySonTheardClass is begining!"<<endl;
        cout<<"作为类参数对象被执行,线程ID:"<<this_thread::get_id()<<endl;
        cout<<"mySonTheardClass is over!"<<endl;
    }
    ~SonTheardClass(){
        cout<<"析构被执行,线程ID"<<this_thread::get_id()<<endl;
    }
public:
    int num;
};

int main(int argc, char *argv[])
{

    cout << "主线程:开始"<<endl;//主线程是从main函数开始执行,执行到return ,主线程结束
    SonTheardClass mySonTheardClass(6);

    thread thread1(mySonTheardClass);//创建线程,线程起点是mySonThread

   thread1.join();//主线程执行到这里开始阻塞,等待mySonThread执行完,主线程继续往下执行

    cout<<"主线程:结束"<<endl;

    return 0;
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47

测试结果

linux 下GCC编译器测试结果:

在这里插入图片描述 对象被拷贝构造了两次后,被析构掉一次,将第一次拷贝构造的对象传入子线程。

Windows下VS2015测试结果

在这里插入图片描述
可以看到,在VS2015平台上,对象仅被拷贝构造一次就被送入到子进程中。

Windows下 VS2013测试结果

在这里插入图片描述
可以看到在VS2013平台上,对象被拷贝构造了三次,而且被传入到子进程中还要进行一次拷贝构造。

结论

因此可以看出不同的编译器或平台,对于thread函数处理的方式是不一样

推荐阅读