C++ thread pass value invoke constructor once and deconstructor many times,while pass ref it only invoke both constructor and deconstructor once

//Pass thread value type 
//
Model//Util.h #ifndef Util_H #define Util_h #include <ctime> #include <chrono> #include <iostream> #include <sstream> #include <thread> #include <uuid/uuid.h> #include <vector> using namespace std; class Util { public: static char *uuidValue; static char *dtValue; static int num; Util(); ~Util(); char *getTimeNow(); char *getUuid(); static void printUuidNum3(int x,Util ul); static void printNumUuid4(int x,Util ul); void mt5(int x,int y,Util ul); }; #endif //Model//Util.cpp #include "Model/Util.h" char *Util::dtValue = (char *)malloc(20); char *Util::uuidValue = (char *)malloc(40); int Util::num = 0; void Util::mt5(int x, int y, Util ul) { thread t1(printUuidNum3, x, ul); t1.join(); thread t2(printNumUuid4, y,ul); t2.join(); cout << getTimeNow() << ",finished in void Util::mt5(int x,int y,Util ul)!" << endl; } void Util::printNumUuid4(int x, Util ul) { for (int i = 0; i < x; i++) { cout << i << "," << ul.getUuid() << endl; } } void Util::printUuidNum3(int x, Util ul) { for (int i = 0; i < x; i++) { cout << ul.getUuid() << "," << i << endl; } } Util::Util() { cout << ++num << ",In constructor!" << endl; } Util::~Util() { cout << --num << ",In deconstructor!" << endl; } char *Util::getUuid() { uuid_t newUUID; uuid_generate(newUUID); uuid_unparse(newUUID, uuidValue); return uuidValue; } char *Util::getTimeNow() { time_t rawTime = time(NULL); struct tm tmInfo = *localtime(&rawTime); strftime(dtValue, 20, "%Y%m%d%H%M%S", &tmInfo); return dtValue; }

//main.cpp #include "Model/Util.h" using namespace std; void mt2(int x,int y); int main(int args, char **argv) { mt2(atoi(argv[1]), atoi(argv[2])); } void mt2(int x,int y) { Util ul; ul.mt5(x,y,ul); }

Compile

g++ -g -std=c++2a -I. *.cpp ./Model/*.cpp -o h1 -luuid -lpthread;

Run 

time ./h1 5 5;

 

 

As the above snapshot illustrates,the constructor run only once,but the deconstructor run 8 times which confused me.

The constructor create the class instance only once,however the deconstructor can destory or dispose the instance 8 times.

 

 

//Model//Util.h
#ifndef Util_H
#define Util_h
#include <ctime>
#include <chrono>
#include <functional>
#include <iostream>
#include <sstream>
#include <thread>
#include <uuid/uuid.h>
#include <vector>

using namespace std;

class Util
{
public:
    static char *uuidValue;
    static char *dtValue;
    static int num;
    Util();
    ~Util();
    char *getTimeNow();
    char *getUuid(); 
    static void printUuidNum6(int x,Util &ul);
    static void printNumUuid7(int x,Util &ul);
    void mt8(int x,int y,Util &ul);
};
#endif


//Model//Util.cpp
#include "Model/Util.h"

int Util::num = 0;
char *Util::dtValue = (char *)malloc(20);
char *Util::uuidValue = (char *)malloc(40);

Util::Util()
{
    cout << ++num << ",In constructor!" << endl;
}

Util::~Util()
{
    cout << --num << ",In deconstructor!" << endl;
}

void Util::mt8(int x,int y,Util &ul)
{
    thread t1(printUuidNum6,x,std::ref(ul));
    t1.join();

    thread t2(printNumUuid7,y,std::ref(ul));
    t2.join();
    cout<<getTimeNow()<<", finished in void Util::mt8(int x,int y,Util &ul)!"<<endl;
}

void Util::printNumUuid7(int x,Util &ul)
{
    for(int i=0;i<x;i++)
    {
        cout<<i<<","<<ul.getUuid()<<endl;
    }
}

void Util::printUuidNum6(int x,Util &ul)
{
    for(int i=0;i<x;i++)
    {
        cout<<ul.getUuid()<<","<<i<<endl;
    }
}

char *Util::getUuid()
{
    uuid_t newUUID;
    uuid_generate(newUUID);
    uuid_unparse(newUUID, uuidValue);
    return uuidValue;
}

char *Util::getTimeNow()
{
    time_t rawTime = time(NULL);
    struct tm tmInfo = *localtime(&rawTime);
    strftime(dtValue, 20, "%Y%m%d%H%M%S", &tmInfo);
    return dtValue;
}


//main.cpp

#include "Model/Util.h"

using namespace std; 

void mt3(int x,int y);

int main(int args, char **argv)
{
    mt3(atoi(argv[1]), atoi(argv[2])); 
}

void mt3(int x,int y)
{
    Util ul;
    ul.mt8(x,y,std::ref(ul));
}

Compile

g++ -g -std=c++2a -I. *.cpp ./Model/*.cpp -o h1 -luuid -lpthread;

Run

time ./h1 10 10;

 

 

 

As the above snapshot illustrates that when I pass reference type in thread,it will only invoke deconstructor once.

posted @ 2022-06-20 23:00  FredGrit  阅读(22)  评论(0编辑  收藏  举报