代码之家  ›  专栏  ›  技术社区  ›  Amir Rasti

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

  •  -1
  • Amir Rasti  · 技术社区  · 8 年前

    根据下面的代码,myClass1对象和myClass2对象(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();
     ........
    }
    
    2 回复  |  直到 8 年前
        1
  •  1
  •   Caleth    8 年前

    就目前而言 main 将呼叫 std::terminate ,因为您放弃了可接合 std::thread

    如果你加入它, 主要的 将阻塞,直到线程完成。 object 将在的整个期间保持活动状态 Run

    如果你拆开它, 主要的 也许 在线程结束之前结束, 对象 将不复存在 this 在里面 myClass1::Run 将无效。未定义的行为。

    整理您的代码

    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;
    }
    
        2
  •  1
  •   UKMonkey    8 年前

    不创建线程并不会神奇地使线程拥有该内存的所有权。如果在堆栈上创建对象,请创建使用该对象的线程;然后展开堆栈,销毁对象;线程仍在运行时,您将有未定义的行为。

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