[英]How can I create a new thread from a c++ boost thread_group that begins execution in a member function of an object?
[英]Can C++ std::thread callable's object pointer be invalidated after the thread begins execution?
我有这段代码...
一个非静态成员方法(作为线程的可调用方法):
void Object::unregister()
{
...
}
和这样的析构函数:
Object::~Object()
{
std::thread cleanup(&Object::unregister, this);
cleanup.detach();
}
我看到的一个问题是我正在运行一个带有参数this
的线程,当析构函数完成时它变得无效,所以我认为这是危险的,因为我没有任何保证,清理线程已经开始 - 这是我的子问题 -如果在unregister
的调用完全完成之前this
将失效(析构函数完成)是安全的(换句话说,如果它已经开始,但没有完全完成)可以吗?
我会说答案是否定的,因为this
指针的副本与 callable 一起使用,但我不确定应用程序的行为,就像它不介意并且一切正常。
如果线程刚刚开始但还没有结束没问题,有没有办法知道线程已经在运行? 调用joinable()
是否会在线程已经执行时返回true
,或者它可以在线程执行开始之前返回true
?
有什么方法可以安全地做到这一点并确保可调用的&Object::unregister
并且this
不会失效,因为Object
同时被破坏了?
如果在取消注册的调用完全完成之前这将失效(析构函数完成)是安全的(换句话说,如果它已经开始,但没有完全完成)可以吗?
不,这不安全。
考虑以下 C 代码:
void Object_unregister(void* obj)
{
Object* this = (Object*)obj;
fclose(this->file_handle);
while (this->ref_counter > 0) {
fclose(this->ref_array[this->ref_counter]->handle);
free(this->ref_array[this->ref_counter]);
this->ref_array[this->ref_counter] = NULL;
--this->ref_counter;
}
}
void destroy_Object(Object** this)
{
pthread_t thread;
pthread_create(&thread, NULL, &Object_unregister, (void*)*this);
pthread_detach(&thread);
free(*this);
*this = NULL;
}
这就是你的 C++ 代码在做的最基本的事情。 在此代码中,我们创建线程,然后将其分离,然后立即释放 Object 所在的Object
空间。 这样,不能保证Object_unregister
function 中的this
指针将指向传递给它的相同Object
。
有一个(一般)保证,线程 function 仍将指向与创建线程相同的 function 指针地址,并且它将一直运行到this
指针将指向与调用 function 时相同的 memory 地址。
但...
this
可能指向0xABADCAFE
并且this->file_handle
将指向this + sizeof(Object::file_handle)
,但是如果您删除了 object,那么该地址的实际内容可能不再指向Object
的有效引用类型。
It could point to some random bit of encryption code, or a new function, or just about anything, but it could still point to the object that was originally there if that memory space was not reallocated by the kernel.
所以不,这不安全。
有什么方法可以安全地做到这一点并确保可调用的
&Object::unregister
并且this
不会失效,因为Object
同时被破坏了?
好吧,这取决于您的Object::unregister
代码在代码的 rest 上下文中实际执行的操作。 目前还不清楚为什么要线程化析构函数并且不只是调用this->unregister();
在析构函数中,例如:
Object::~Object()
{
this->unregister();
}
这与您在代码上下文中获得的一样安全。
但是,如果还有其他事情必须以线程方式完成,您可以做许多架构上的事情来线程化 object 的破坏,从 static 值到锁定机制,但基本上您需要做的是复制您需要unregister
的特定值,以便它们在您的线程代码中保持有效。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.