c++ 从成员函数创建新线程并移动对象和整个对象

c++ Creating a new thread from a member function and moving the object and the entire

本文关键字:对象 移动 线程 成员 函数 创建 新线程 c++      更新时间:2023-10-16

根据下面的代码,myClass1 对象和 myClass2 obj(这是 myClass1 对象的成员(是否随着它们的内存移动到新线程(如 std::move(((?

class myClass1{
  public:
   myClass2 obj;
    myClass1(myClass2 * obj) {
        this.obj = *obj;
    }
    thread spawn() {
        return std::thread([this] { this->Run(); });
    }
    void Run() {
        cout << "new thread" << endl;
    }
}
myClass2{
   public :
    string str;
  MyClass2(string str){
    this.str = str;
}
}
int main(){
  myClass1 object(new myClass2("test"));
  thread t = object.spawn();
 t.join();
 ........
}

就目前而言,您的main将调用 std::terminate ,因为您丢弃了可连接的std::thread

如果您加入它,main将阻止,直到线程完成。 object将在整个Run期间保持活力。

如果将其分离,main可能会在线程之前结束,object将不复存在,并且myClass1::Run中的this将无效。未定义的行为。

整理

您的代码

class myClass1 {
    myClass2 obj;
public:
    // Take by rvalue, uses the move constructor for obj
    myClass1(myClass2 && obj) : obj(obj) {}
    std::thread spawn() {
        return std::thread([this] 
        {
            // This is suspicious, but safe
            auto self = std::move(*this); 
            self.Run(); 
        });
    }
    void Run() {
        std::cout << "new thread" << std::endl;
    }
}
int main(){
    // new is not required
    myClass1 object(myClass2("test"));
    object.spawn().join();
    /* other stuff, not involving object */
    return 0;
}

更像是整理

class myClass1 {
    myClass2 obj;
public:
    // Take by rvalue, uses the move constructor for obj
    myClass1(myClass2 && obj) : obj(obj) {}
    void Run() {
        std::cout << "new thread" << std::endl;
    }
}
int main() {
    // Just create the instance of myClass1 as a parameter to `std::thread`'s constructor
    std::thread(&myClass1::Run, myClass1(myClass2("test"))).join();
    /* other stuff */
    return 0;
}

不;创建线程不会神奇地使线程获得该内存的所有权。 如果在堆栈上创建对象,请创建一个使用该对象的线程;然后展开堆栈,破坏物体;当线程仍在运行时,您将有未定义的行为。

如果要将某些数据的所有权授予线程,最简单的方法是使用共享指针。