为什么 "boost.thread" 手动调用 "intrusive_ptr_add_ref"?

why "boost.thread" call "intrusive_ptr_add_ref" manually?

在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之前,count已经是1了,不知道为什么调用intrusive_ptr_add_ref 在这里手动。我认为侵入式智能指针的工作应该是自动调用 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_start_function 被调用之前调用 thread::detach 。如果发生这种情况,那么 thread_info 侵入式指针将被破坏,从而导致其包含的对象被破坏。

然后 _beginthreadex 留下了一个被破坏的指针。太糟糕了。

_beginthreadex 需要做的是声明对 intrusvie 指针的所有权。但是由于 API 不接受 boost::intrusive_ptr,你是怎么做到的?

通过增加引用计数。引用计数增加是 _beginthreadex 声明对象所有权的方式。