2014-01-31 9 views
11

Mein Problem ist, dass ich mehrere Threads habe, sie sind in einem Container gespeichert, und ich muss wissen, wann ein Thread an einer bestimmten Position beendet ist. Auf Fenster würde ich so etwas wie:WaitForMultipleObjects Alternative mit Std :: Thread?

HANDLE handles[3]; 
//handles were initialized 
DWORD finishingThread = WaitForMultipleObjects(3, handles, false, INFINITE) 

Gibt es einen Weg, um die gleiche Wirkung mit std :: Thread zu erreichen?

+0

Schauen Sie sich hier ein: http://stackoverflow.com/questions/10818254/learning-threads-on-linux – marcinj

+0

@marcin_j diese Frage nicht nur informativ, es ist wohl ein Outright-Dupe von diesem (oder vielmehr es ist umgekehrt). Danke für die Verknüpfung. Und zum OP, nein, nicht nativ ohne etwas Arbeit von Ihrer Seite. Solch eine willkürliche Thread-Exit-Erkennung befindet sich nicht in der Thread-Support-Bibliothek, jedenfalls nicht, die ich je gesehen habe. – WhozCraig

+0

Wenn Sie auf Windows sind und es nur mehr C++ ish behalten wollen, dann ist die [Concurrency Runtime] (http://msdn.microsoft.com/en-us/library/dd504870.aspx) eine gute Wahl. Microsofts "std :: thread" - und "std :: async" -Implementierung baut auf VS2013 auf. – Mgetz

Antwort

4

Nach meinem besten Wissen gibt es nichts in der Standardbibliothek, das ein Warten dieser Art unterstützt. Die Standardbibliothek baut auf der zugrunde liegenden Betriebssystem-Threading-Unterstützung auf. Notfalls kann die Standardbibliothek nur die Funktionalität des kleinsten gemeinsamen Nenners bieten. Dies bedeutet, dass es nicht in der Lage ist, einige der umfangreicheren Funktionen der Win32-Threading-Bibliothek zu übernehmen.

-1

Was Sie wollen, ist etwas, das Boost :: thread_group entspricht.

Gibt es nicht, aber Sie können diese Funktionalität schreiben: A std :: vector und std :: for_each, um join()/WaitForSingleObject für jedes Element aufzurufen oder natürlich nach einer dritten Partei zu suchen, die dasselbe tut cppthreadpool

4

Verwenden Sie einfach eine std::condition_variable und lassen Sie Ihre Threads direkt vor dem Ende notify_all() oder notify_one() feuern.

Dann tun Sie cv.wait(), wo Sie Ihre WaitForMultipleObjects() aufrufen möchten.

+0

Dies ist keine Antwort auf die Frage, weil std :: condition_variable es ermöglicht, einen oder mehrere wartende Threads über den Zustand eines bestimmten Objekts (insbesondere eines Threads) zu benachrichtigen. Mit WaitForMultipleObjects() kann ein Thread über die Zustände mehrerer Objekte in mehreren Threads benachrichtigt werden. – Jurlie

2

Hier ist ein Beispiel dafür, wie man die gleiche Wirkung erzielen kann mit std::thread und std::future, wenn Sie bereit sind, den Haupt-Thread schlafen zu lassen, während Polling die Bereitschaft der Fäden (alternativ Sie ein dedizierter Thread die Warte behandeln lassen konnte).

diese Funktion Betrachten wir eine Reihe von Iteratoren in einen Behälter mit std::future nehmen, die bis zumindest eine Aufgabe beendet ist blockiert:

const int TIME_BETWEEN_POLLS_MS = 50; 

// Wait (sleep) between polls until a task is finished then return iterator to future. 
template <typename Iterator> 
Iterator waitForFirst(Iterator first, Iterator last) { 
    auto it = first; 
    auto status = std::future_status::timeout; 
    while (status != std::future_status::ready) { 
     if (++it == last) { // Rotate in range. 
      it = first; 
     } 
     status = it->wait_for(std::chrono::milliseconds(TIME_BETWEEN_POLLS_MS)); 
    } 
    return it; 
} 

Nun, wenn Sie einen Container von Futures (std::future) haben Mit den Rückgabewerten Ihrer Aufgaben, die auf separaten Threads ausgeführt werden, können Sie einfach die Funktion waitForFirst verwenden, um einen Iterator für die Zukunft zu erhalten, der sein Ergebnis zuerst erhält.

// Lets say you have a vector of futures, e.g. 
    std::vector<std::future<std::thread::id>> futures; 

    /* Push futures to vector... */ 

    // Block until first task is finished. 
    // 'it' is iterator to future associated with result. 
    auto it = finishingThread(std::begin(futures), std::end(futures)); 

Siehe live example

Verwandte Themen