Ich möchte einen Thread mit 2 Threads warten, der in einem Simultansimulator ausgeführt wurde, bis eine Bedingung aufgetreten ist. Möglicherweise ist die Bedingung nach 1000 oder mehr Zyklen beim Ausführen eines Programms im Simulator aufgetreten , nachdem die Bedingung aufgetreten ist, wurde der wartende Thread erneut ausgeführt. Wie kann ich das tun?wartender Thread, bis eine Bedingung aufgetreten ist
Antwort
Sie benötigen Bedingungsvariablen.
Wenn Ihr Compiler unterstützt std::conditional
eingeführt durch C 11 ++, dann können Sie diese sehen für Detail:
Wenn Ihr Compiler nicht unterstützt, und Sie arbeiten mit win32 Fäden, dann sehen:
Und here ist ein komplettes Beispiel.
Und wenn Sie mit POSIX-Threads arbeiten, dann sehen:
Sie können meine Implementierung von conditional_variable
mit win32 Primitiven hier sehen:
Scrollen Sie nach unten und sehen Sie zuerst die Implementierung und dann die Verwendung in der Implementierung der gleichzeitigen Warteschlange.
Eine typische Verwendung von Bedingungsvariable ist dies:
//lock the mutex first!
scoped_lock myLock(myMutex);
//wait till a condition is met
myConditionalVariable.wait(myLock, CheckCondition);
//Execute this code only if the condition is met
wo CheckCondition
eine Funktion (oder Funktors) ist, die die Bedingung überprüft. Es wird von wait()
Funktion intern aufgerufen, wenn es fälschlicherweise aufwacht und wenn die Bedingung noch nicht erfüllt ist, schläft die wait()
Funktion wieder. Bevor Sie schlafen gehen, gibt wait()
den Mutex frei, atomar.
Wenn Sie kein C++ 11 haben, aber ein System, das POSIX-Threads unterstützt, können Sie eine Bedingungsvariable verwenden. Es gibt andere Möglichkeiten, aber eine Zustandsvariable kann am einfachsten sein, wenn Sie Ihr Problem beschrieben haben.
Eine PThread-Zustandsvariable wird in Verbindung mit einem Mutex verwendet. Der Trick mit der Bedingungsvariablen ist, dass das Warten darauf den freigegebenen Mutex freigibt, bis der Warteaufruf zurückkehrt, an welchem Punkt der Mutex erneut erfasst wurde.Die Reihenfolge ist:
- acquire Mutex
- während PREDICATE nicht wahr ist
- Warten auf Bedingungsvariable
- Arbeit an kritischen Abschnitt tun
- wenn PREDICATE wahr ist
- Signalbedingungsvariable
- Release Mutex
Das Signal Schritt wird im Falle mehrerer Threads denselben kritischen Abschnitt eintreten oben verwendet.
Wenn ein anderer Thread auf den gleichen Mutex-Status zugreifen kann, der die PREDICATE beeinflusst, sollte dieser Thread prüfen, ob jemand signalisiert werden muss.
- acquire Mutex
- auf kritischen Abschnitt funktionieren, wenn PREDICATE
- Signalbedingungsvariable
- Release Mutex
Die POSIX-Befehle von Interesse wahr sind :
pthread_mutex_init()
pthread_mutex_destroy()
pthread_mutex_lock()
pthread_mutex_unlock()
pthread_cond_init()
pthread_cond_destroy()
pthread_cond_wait()
pthread_cond_signal()
Verwendung von Semaphor zur Signalisierung. Beispiel (Anwendung sauber Ausgang), wie nachstehend:
Deklarieren in header
static sem_t semPrepareExit; //declaration
in der Quelle (Haupt-Thread);
sem_init(&semPrepareExit, 0, 0); ///semaphore initialized
...
///now wait for the signal on the semaphore, to proceed hereforth
sem_post(&semPrepareExit);
/// cleanup ahead
...
In Quelle, (Laich-Thread);
...
sem_post(&semPrepareExit);
Jetzt, sobald Sie auf dem Semaphor mit "sem_post" signalisieren. Der Haupt-Thread wird das Signal an dem Warteknoten/-punkt empfangen und wird fortfahren, da-her.
versuchen, etwas wie folgt aus:
class CmyClass
{
boost::mutex mtxEventWait;
bool WaitForEvent(long milliseconds);
boost::condition cndSignalEvent;
};
bool CmyClass::WaitForEvent(long milliseconds)
{
boost::mutex::scoped_lock mtxWaitLock(mtxEventWait);
boost::posix_time::time_duration wait_duration = boost::posix_time::milliseconds(milliseconds);
boost::system_time const timeout=boost::get_system_time()+wait_duration;
return cndSignalEvent.timed_wait(mtxEventWait,timeout); // wait until signal Event
}
// so inorder, um dann das Verfahren waitforevent warten rufen
WaitForEvent(1000); // it will timeout after 1 second
// dies ist, wie ein Ereignis signalisiert werden könnte:
cndSignalEvent.notify_one();
Suchbedingte Variablen und Semaphore. –
Werfen Sie auch einen Blick auf Versprechen und Futures (http://en.cppreference.com/w/cpp/thread/promise) –