在boost.thread的start函数中,源码是这样的:
bool thread::start_thread_noexcept()
{
uintptr_t const new_thread = _beginthreadex(
0,
0,
&thread_start_function,
thread_info.get(),
CREATE_SUSPENDED,
&thread_info->id);
if (!new_thread)
{
return false;
}
// why call this line?
intrusive_ptr_add_ref(thread_info.get());
thread_info->thread_handle = (detail::win32::handle)(new_thread);
ResumeThread(thread_info->thread_handle);
return true;
}
thread_info是一个侵入式智能指针,指向线程信息数据,在调用intrusive_ptr_add_ref之前,计数已经为1,不知道这里为什么要手动调用intrusive_ptr_add_ref。我认为 Intrusive 智能指针的工作应该是自动调用 intrusive_ptr_add_ref 和 intrusive_ptr_release。
我试图逐步查看源代码,但没有找到任何线索。
谁能告诉我 1、这里为什么要手动调用intrusive_ptr_add_ref? 2. 什么情况下使用intrusive_ptr,需要手动调用intrusive_ptr_add_ref?
谢谢,真诚的。
最佳答案
why call intrusive_ptr_add_ref manually here?
代表共享指针的所有权。
_beginthreadex
作为参数传递给 thread_info.get()
。这个参数会在线程启动时传递给thread_start_function
。并且此函数期望指针在发生这种情况之前保持有效。
现在,_beginthreadex
是一个简单的函数。它不是可以采用任意参数或任何参数的可变参数模板。它只接受一个裸指针,并将其准确传递给启动函数。
创建 boost::thread
的人很有可能调用 thread::detach
before thread_start_function
曾经被调用过。如果发生这种情况,thread_info
侵入指针将被破坏,从而导致其包含的对象被破坏。
这使得 _beginthreadex
带有一个已销毁的指针。这很糟糕。
_beginthreadex
需要做的是声明对 intrusvie 指针的所有权。但由于 API 不采用 boost::intrusive_ptr
,您如何做到这一点?
通过增加引用计数。引用计数增加是 _beginthreadex
声明对象所有权的方式。
关于c++ - 为什么 "boost.thread"手动调用 "intrusive_ptr_add_ref"?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38908715/