在boost.thread的启动函数中,源代码是这样的:
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?
谢谢,真诚。
答案 0 :(得分:1)
为什么在这里手动调用intrusive_ptr_add_ref?
表示指针所有权的共享。
_beginthreadex
已作为参数传递thread_info.get()
。线程启动时,此参数将传递给thread_start_function
。此函数希望指针在发生之前保持有效。
现在,_beginthreadex
是一个简单的功能。它不是可以采用任意参数或任何参数的可变参数模板。它只需要一个裸指针,并将其完全传递给start函数。
创建boost::thread
的人很有可能在 thread::detach
被调用之前调用thread_start_function
。如果发生这种情况,那么thread_info
侵入式指针将被销毁,从而导致其所包含对象的破坏。
这会使_beginthreadex
留下一个被破坏的指针。那太糟糕了。
_beginthreadex
需要做的是声明对intrusvie指针的所有权。但由于API没有boost::intrusive_ptr
,你怎么做?
通过提高引用计数。引用计数增加是_beginthreadex
声明对象所有权的方式。