![](/img/trans.png)
[英]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.