Je veux attendre qu'un thread de 2 threads exécuté dans un simulateur simultané jusqu'à ce qu'une condition soit apparue. Cette condition peut être apparue après 1000 cycles ou plus d'exécution d'un programme dans le simulateur. Comment puis-je le faire?
Vous avez besoin de variables conditionnelles.
Si votre compilateur supporte std::conditional
introduit par C++ 11, vous pouvez le voir pour plus de détails:
Si votre compilateur ne le supporte pas et que vous travaillez avec des threads win32, voyez ceci:
Et ici est un exemple complet.
Et si vous travaillez avec des threads POSIX, voyez ceci:
Vous pouvez voir mon implémentation de conditional_variable
en utilisant les primitives win32 ici:
Faites défiler l'écran vers le bas et voyez d'abord son implémentation, puis voyez l'utilisation dans l'implémentation de la file d'attente simultanée.
Une utilisation typique de variable conditionnelle est la suivante:
//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
oùCheckCondition
est une fonction (ou un foncteur) qui vérifie la condition. Elle est appelée en interne par la fonction wait()
lorsqu'elle de façon éhontée se réveille et si la condition n'est pas encore remplie, la fonction wait()
se met en veille. Avant de dormir, wait()
libère le mutex, atomiquement.
Si vous n'avez pas C++ 11, mais que vous avez un système qui prend en charge les threads POSIX, vous pouvez utiliser une variable de condition. Il existe d'autres choix, mais une variable de condition peut être la plus simple, compte tenu de la façon dont vous avez décrit votre problème.
Une variable de condition pthread est utilisée conjointement avec un mutex. Le truc avec la variable de condition est que l’attente provoque la libération du mutex acquis, jusqu’au retour de l’appel d’attente, date à laquelle le mutex a de nouveau été acquis. La séquence est:
L'étape de signal est utilisée dans le cas où plusieurs threads entrent dans la même section critique ci-dessus.
Si un thread différent peut accéder au même mutex pour modifier l'état qui affecte le PREDICATE, ce thread doit vérifier si quelqu'un doit être signalé.
Les commandes POSIX d’intérêt sont:
pthread_mutex_init()
pthread_mutex_destroy()
pthread_mutex_lock()
pthread_mutex_unlock()
pthread_cond_init()
pthread_cond_destroy()
pthread_cond_wait()
pthread_cond_signal()
Utilisation de Semaphore pour la signalisation. Exemple (sortie propre de l'application) comme ci-dessous:
Déclarer en tête
static sem_t semPrepareExit; //declaration
En source (filetage principal);
sem_init(&semPrepareExit, 0, 0); ///semaphore initialized
...
///now wait for the signal on the semaphore, to proceed hereforth
sem_post(&semPrepareExit);
/// cleanup ahead
...
Dans la source, (spawned-thread);
...
sem_post(&semPrepareExit);
Maintenant, dès que vous signalez le sémaphore en utilisant "sem_post". Le thread principal recevra le signal au noeud/point d'attente et procédera par la suite.
essayez quelque chose comme ça:
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
}
// afin d'attendre puis appeler la méthode WaitForEvent
WaitForEvent(1000); // it will timeout after 1 second
// voici comment un événement pourrait être signalé:
cndSignalEvent.notify_one();