2016-08-12 65 views
2

在boost.thread的启动功能,源代码是类似的东西:为什么“boost.thread”手动调用“intrusive_ptr_add_ref”?

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?

谢谢,真诚。

回答

1

为什么要在这里手动调用intrusive_ptr_add_ref?

表示指针所有权的共享。

_beginthreadex作为参数通过thread_info.get()。线程启动时,此参数将传递给thread_start_function。这个函数期望指针保持有效,直到发生这种情况。

现在,_beginthreadex是一个简单的功能。它不是可变参数或任何参数的可变参数模板。它只需要一个裸指针,并将其精确地传递给启动函数。

这是非常可能用于创建boost::threadthread_start_function曾经被调用之前调用thread::detach的人。如果发生这种情况,那么这个入侵指针将被破坏,从而导致它所包含的对象被破坏。

而且叶子_beginthreadex销毁指针。那很糟。

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

通过颠倒引用计数。引用计数增加是_beginthreadex如何声明对象的所有权。

+0

非常感谢!你的回答非常有价值,并且揭示了一切! – zach