2016-08-12 1 views
2

In Boost.Thread der Start-Funktion, die Quellcode ist so etwas wie die:Warum "boost.thread" "intrusive_ptr_add_ref" manuell aufrufen?

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 ist ein intrusive intelligenten Zeiger, der auf die Faden Informationsdaten zeigt, bevor die intrusive_ptr_add_ref Aufruf, ist die Zählung bereits 1, I Ich weiß nicht, warum man die intrusive_ptr_add_ref hier manuell aufruft. Ich denke, der Job des intrusiven intelligenten Zeigers sollte die intrusive_ptr_add_ref- und intrusive_ptr_release automatisch aufrufen.

Ich habe versucht, durch den Quellcode zu gehen, fand aber keine Hinweise.

Kann mir jemand sagen 1. warum intrusive_ptr_add_ref hier manuell aufrufen? 2. In welchem ​​Zustand sollte intrusive_ptr intrusive_ptr_add_ref manuell aufgerufen werden?

Danke, Mit freundlichen Grüßen.

Antwort

1

warum intrusive_ptr_add_ref hier manuell aufrufen?

Um die gemeinsame Nutzung des Besitzers des Zeigers darzustellen.

_beginthreadex wurde als Parameter thread_info.get() übergeben. Dieser Parameter wird beim Starten des Threads an thread_start_function übergeben. Und diese Funktion erwartet, dass der Zeiger bis zu diesem Zeitpunkt gültig bleibt.

Jetzt ist _beginthreadex eine einfache Funktion. Es ist keine variable Vorlage, die beliebige Parameter oder irgendetwas annehmen kann. Es nimmt genau und nur einen nackten Zeiger und übergibt genau das an die Startfunktion.

Es ist sehr möglich, dass die Person, die die boost::thread Schaffung thread::detachvor nennen thread_start_function jemals aufgerufen wird. Und wenn das passiert wäre, würde der intrusive Zeiger thread_info zerstört werden, was zur Zerstörung seines enthaltenen Objekts führen würde.

Und das verlässt _beginthreadex mit einem zerstörten Zeiger. Das ist schlecht.

Was _beginthreadex tun muss, ist Besitzanspruch auf den Intrusvie-Zeiger. Aber da die API keine boost::intrusive_ptr nimmt, wie machst du das?

Durch Stoßen der Referenzzählung. Die Referenzzahlerhöhung ist, wie _beginthreadex Anspruch auf das Eigentum des Objekts.

+0

Vielen Dank! Ihre Antwort ist so wertvoll und enthüllt alles! – zach

Verwandte Themen