2012-02-02 13 views
8

Obecnie tworzę podstawową pulę wątków. Użyłem C++ 11: std::thread, wraz z std::condition_variable i std::unique_lock. Wydaje się, że działa i chciałbym teraz móc zabijać wątki, gdy zbyt wiele z nich jest nieaktywnych. Na razie ich prace są wykonywane przez std::queue z boost::function. Myślałem o dodaniu paczki pustych boost::function s, więc wątki wiedzą, że muszą wyjść z pętli. pętli wątku jest tak:Pobierz std :: thread, aby się odłączyć i zakończyć samoczynnie

void ThreadPool::threadLoop() 
{ 
    boost::function<void()>  oThreadTask; 
    std::unique_lock<std::mutex> oLock(m_oTaskMutex); 

    while (1) 
    { 
     // m_oCV is a static std::condition_variable 
     // m_oTaskQueue is a static std::queue< boost::function<void()> > 
     m_oCV.wait(oLock, [](){ return m_oTaskQueue.size(); }); 
     oThreadTask = m_oTaskQueue.front(); 
     m_oTaskQueue.pop(); 
     m_oTaskMutex.unlock(); 
     if (oThreadTask.empty()) 
     break ; 
     oThreadTask(); 
    } 
    // ?? 
} 

Chodzi o to, że nie jestem pewien, jak prawidłowo odłączyć wątek kiedyś wyszedł z pętli. Czy można odszukać uchwyt nici (mam dostęp do std::list<std::thread*> i mogę porównać ich identyfikatory z std::this_thread::get_id()) i czy można bezpiecznie wywołać detach() z samego wątku, czy nawet join()?

Odpowiedz

11

Tak, jeśli masz zapisane wszystkie obiekty wątku, można znaleźć taki, który thread::id jest równa this_thread::get_id() i można zadzwonić detach() na niego i zniszczyć obiekt po tym wątku (średnia w C++ 11 nie zapobiegać temu i uważam, że opiera się na powszechnej praktyce). Upewnij się, że żaden inny wątek wykonywania nie uzyskuje dostępu do instancji std::thread, która jest zniszczona.

Ale nie można nazwać join() od samego wątku: próba dla wątku, aby przyłączyć się do siebie doprowadziłoby do impasu i C++ 11 wdrożeń należy uznać, że i rzucać system_error ze stanu błędu resource_deadlock_would_occur.

Alternatywnie, możesz zostawić wiadomość (np. Przez zmienną std :: atomic) do głównego wątku, który wątek związany z konkretnym wystąpieniem std::thread ma wkrótce ukończyć jego wykonanie, i niech główny wątek zostanie połączony z tym wystąpienie w późniejszym punkcie.

+0

Dziękuję. Najprostszym sposobem będzie prawdopodobnie oderwanie się nici. – Jukurrpa

Powiązane problemy