Comment utiliser un condition_variable vraiment wait_for pas dépasser une certaine durée
Comme il s'avère, condition_variable::wait_for
devrait vraiment être appelé condition_variable::wait_for_or_possibly_indefinitely_longer_than
, car il a besoin d'acquérir le verrou avant de vraiment le timing et le renvoi.
Voir ce programme pour une démonstration.
Est-il un moyen d'exprimer, "Regardez, je n'ai que deux secondes. Si myPredicate()
est toujours faux à l'époque et/ou de l'écluse est toujours bloqué, je n'ai pas de soins, vient de porter sur indépendamment et de me donner un moyen de détecter que."
Quelque chose comme:
bool myPredicate();
auto sec = std::chrono::seconds(1);
bool pred;
std::condition_variable::cv_status timedOut;
std::tie( pred, timedOut ) =
cv.really_wait_for_no_longer_than( lck, 2*sec, myPredicate );
if( lck.owns_lock() ) {
//Can use mutexed resource.
//...
lck.unlock();
} else {
//Cannot use mutexed resource. Deal with it.
};
wait_until
peut-être?J'ai peur
wait_until
, souffre de la même "fonction". "Une fois notifié, ou une fois qu'il est abs_time
, la fonction permet de débloquer et d'appels lck.lock()
, laissant lck
dans le même état que lorsque la fonction a été appelée. Alors la fonction renvoie (notez que cette dernière mutex verrouillage peut bloquer à nouveau le fil avant de revenir)."Si vous ne voulez pas être l'acquisition d'un mutex sur l'éveil, les variables de condition de ne pas travailler pour vous, dans n'importe quelle langue.
Juste assez, merci. Comment le feriez-vous? timed_mutex/serrures?
OriginalL'auteur Julian | 2014-08-08
Vous devez vous connecter pour publier un commentaire.
Je pense que vous abusez de la
condition_variable
's de verrouillage. C'est pour protéger la seule condition, pas de la protection d'un travail de longue haleine.Votre exemple peut facilement être corrigé par le fractionnement de la
mutex
en deux - l'une est pour de la section critique, l'autre est pour la protection de modifications deready
condition. Voici le fragment modifié:Elle est sortie:
Un autre point à préciser est que le code qui acquiert un mutex ne devrait généralement pas la tenir pendant de longues périodes de temps. En particulier si d'autres domaines que d'acquérir le mutex ne peut pas se permettre de bloquer pour que longue période de temps.
OriginalL'auteur Anton
En fait, la
condition_variable::wait_for
fait exactement ce que vous voulez. Le problème avec votre exemple est que vous avez verrouillé à 2 seconde de sommeil avec leready = true
d'affectation, ce qui rend impossible pour la variable de condition à même d'évaluer le prédicat avant d'atteindre la limite de temps.Mettre que
std::this_thread::sleep_for(2*sec);
ligne à l'extérieur de la serrure et de voir par vous-même.OriginalL'auteur Carlos Junior
Oui, il ya un moyen, mais, malheureusement, dans le cas de
wait_for
il doit être manuelle. Lewait_for
attend indéfiniment en raison de Fallacieux De Réveil. Imaginez que votre boucle comme ceci:Le faux réveil peut se produire à tout moment dans un arbitraire de la plate-forme. Imaginez que, dans votre cas, il se produit à moins de 200 ms. Pour cette raison, sans aucune externes notification
wait_for()
permettra de réveil et de vérifiermyPredicate()
dans la condition de la boucle.Comme prévu, la condition sera fausse, donc la boucle va être vrai et encore, il va exécuter
cv.wait_for(..)
, avec des produits frais de 2 secondes. C'est de cette façon, il sera exécuté à l'infini.Soit vous contrôlez que la mise à jour de la durée par vous-même ou utiliser
wait_until()
qui est finalement appelé àwait_for()
.OriginalL'auteur iammilind