C++ c++;从成员函数创建新线程并移动对象和整个
根据下面的代码,myClass1对象和myClass2对象(myClass1对象的成员)是否正在使用内存(如std::move())移动到新线程C++ c++;从成员函数创建新线程并移动对象和整个,c++,multithreading,c++11,memory,C++,Multithreading,C++11,Memory,根据下面的代码,myClass1对象和myClass2对象(myClass1对象的成员)是否正在使用内存(如std::move())移动到新线程 类myClass1{ 公众: myClass2 obj; myClass1(myClass2*obj){ this.obj=*obj; } 线程繁殖(){ 返回std::thread([this]{this->Run();}); } 无效运行(){ coutNo;创建线程并不会神奇地使线程拥有该内存。如果在堆栈上创建对象,则创建使用该对象的线程;然后释
类myClass1{
公众:
myClass2 obj;
myClass1(myClass2*obj){
this.obj=*obj;
}
线程繁殖(){
返回std::thread([this]{this->Run();});
}
无效运行(){
coutNo;创建线程并不会神奇地使线程拥有该内存。如果在堆栈上创建对象,则创建使用该对象的线程;然后释放堆栈,销毁该对象;线程仍在运行,则会有未定义的行为
如果要将某些数据的所有权授予线程,最简单的方法是使用共享指针。目前,您的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;
}
类myClass1{
myClass2 obj;
公众:
//通过右值获取,使用obj的移动构造函数
myClass1(myClass2&&obj):obj(obj){}
std::thread spawn(){
返回std::thread([this]
{
//这很可疑,但很安全
自动自=标准::移动(*此);
self.Run();
});
}
无效运行(){
std::这甚至可以编译吗?请尝试创建一个并向我们展示。这只是为了展示概念,但是如果你想编译它,它应该有一个新线程的连接和myclass2的定义:)“它应该有…”您应该提供它您仍然没有可编译的示例。在您的构造函数中,this.obj=obj;
是一个类型错误。您想要类型为myClass2
的值还是一个(n)原始指针指向myClass2
?谢谢,在我的情况下,我想把我的obj及其所有字段的所有权交给新线程,这样如果线程完成,所有内存都会被释放。如果你修改此代码来实现这一点,我将给出你的答案。谢谢Dar Caleth我知道你的观点,正如我在问题的评论中提到的,最后我的问题是通过移动内存将对象移动到它自己的成员func中too@AmirRasti您不移动任何对象。您创建this
指针的副本,它将成为Run
中的this
指针。您必须std::move(*this)
进入lambda中的一个本地,然后在该本地调用Run,然后请将其作为一个答案发布,然后单击它。@AmirRasti我有另一个选择,即跳过std::move(*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;
}