2016-08-12 103 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