Départ retardé d'un thread en C++ 11
Je suis en C++11 fils et l'ont exécuté un problème.
Je veux déclarer un thread variable comme globale et le lancer plus tard.
Cependant, tous les exemples que j'ai vu semblent commencer immédiatement le thread par exemple
thread t(doSomething);
Ce que je veux, c'est
thread t;
et démarrer le thread plus tard.
Ce que j'ai essayé est
if(!isThreadRunning)
{
thread t(readTable);
}
mais maintenant, t est le bloc de portée. Je tiens donc à déclarer t et ensuite démarrer le thread plus tard, de sorte que t est accessible à d'autres fonctions.
Merci pour toute aide.
- Combien de temps voulez-vous attendre?
std::this_thread::sleep_for(std::chrono::milliseconds(x));
à l'intérieur du fil?- ^ ce, ou de l'utilisation
unique_ptr< thread >
et d'attribuer un nouveau fil de discussion au point où elle devrait commencer. Cela étant dit: globals sont pour la plupart mal vu. - Je pense que la question n'est pas assez claire. Ce que je fais est en cours d'exécution de mon code dans une boucle, et au début de la boucle de vérifier si le thread est en cours d'exécution et si elle est alors de ne pas commencer de nouveau. Cependant je n'ai plus qu'un seul fichier, donc j'ai besoin d'avoir la discussion variable globale ainsi que d'autres fonctions y ont accès.
- eh bien le unique_ptr pourrait fonctionner? Dans votre boucle d'utilisation
if( !myThreadPtr ){ myThreadPtr.reset( new thread( doDomething ); }
? Mais même alors, votre excuse d'avoir besoin de quelque chose dans les différents fichiers n'a pas de sens. Si elle le faisait, chaque application unique composé de plusieurs fichiers/fonctions dans le monde n'aurait globals et ce n'est pas le cas 😛 - Quel est le problème avec juste
thread t;
, ett = thread(doStuffNow);
cas de besoin? - Juste parce qu'un objet doit être accessible dans plusieurs unités de traduction ne signifie PAS qu'il doit être global. Il n'y a rien de mal avec le passage des références à l'objet de toutes les fonctions qui en ont besoin.
Vous devez vous connecter pour publier un commentaire.
std::thread
par défaut de constructeur instancie unstd::thread
sans de départ ou une représentation du réel fil.De l'opérateur d'affectation se déplace à l'état d'un objet thread, et définit l'attribuées à partir du fil d'objet par défaut-état initialisé:
Cette première constructions temporaires fil objet représentant un nouveau fil de discussion, les transferts, le nouveau thread représentation de l'objet thread qui a un défaut de l'état, et les ensembles de la temporaire de l'objet thread de l'état à l'état par défaut qui ne représentent pas de thread en cours d'exécution. Puis la temporaire de l'objet thread est détruit, à ne rien faire.
Voici un exemple:
Je donnerais le fil d'une variable de condition et une valeur booléenne appelée startRunning (initialement fixée à false). Effectivement, vous commencerez immédiatement le thread sur la création, mais la première chose qu'il serait de suspendre lui-même (à l'aide de la condition_variable) et ensuite seulement commencer le traitement de sa tâche réelle lorsque le condition_variable est signalé depuis l'extérieur (et la startRunning indicateur a la valeur true).
EDIT: PSEUDO-CODE:
EDIT #2: Dans le code ci-dessus, les variables theMutex, startRunning et cond_var doit être accessible par les deux threads. Si vous l'atteindre, en rendant les globals ou en les encapsulant dans une struct /instance de classe est à vous.
Il n'y a pas de "standard" de création d'un thread "suspendu" qui je suppose est ce que tu voulais faire avec le C++ bibliothèque de threads. Parce qu'il n'est pas pris en charge sur chaque plate-forme de fils, il n'est pas là dans l'API C++.
Vous pouvez créer une classe avec toutes les données, il est nécessaire, mais pas réellement exécuter votre fonction de thread. Ce n'est pas la même chose que de créer le fil, mais peut-être ce que vous voulez. Si oui, créer, puis plus tard lier l'objet et de son
operator()
oustart()
fonction ou quel que soit le fil.Vous pourriez voulez que l'id de thread pour votre thread. Cela signifie que vous n'avez réellement besoin pour démarrer la fonction de thread. Cependant, il peut commencer par en attente sur une variable de condition. Vous avez alors le signal ou une diffusion que la variable de condition plus tard, quand vous le voulez continuer à fonctionner. Bien sûr, vous pouvez avoir la fonction vérifier une condition après il reprend dans le cas où vous pourriez avoir décidé de la fermer et de ne pas courir après tout (auquel cas il va juste retourner instantanément).
Vous voudrez peut-être un
std::thread
objet sans fonction. Vous pouvez le faire et de le joindre à une fonction plus tard àrun
cette fonction dans un nouveau thread.std::thread
est juste une bibliothèque standard structure de données. Si le connecté fonction estrun()
, implicitement ou explicitement, est à la discrétion de la norme.Vous pouvez utiliser le pattern singleton. Ou je dirais plutôt antipattern.
À l'intérieur d'un singleton, vous auriez
std::thread
objet encapsulé. Lors du premier accès à un singleton de votre fil sera créé et démarré.Comme antred dit dans réponse, vous pouvez utiliser une variable de condition pour faire le fil de l'attendre dans le début de sa routine.
Scott Meyers dans son livre “Effective C++ Moderne” (le “Point 39: Considérer
void
avenir pour les one-shot de la communication événementielle”) propose d'utiliservoid
-avenir, au lieu de la baisse de niveau des entités (indicateur booléen, variable de condition et mutex). Donc, le problème peut être résolu comme ceci:Scott Meyers met également en garde sur les exceptions dans la deuxième
…
(marqué par layou can do something, thread is like “paused” here
commentaire). Sithread_starter.set_value()
n'est jamais appelé pour certaines raisons (par exemple, en raison de l'exception jette dans la deuxième…
), le thread va attendre éternellement, et toute tentative de le rejoindre il en résulterait dans l'impasse.Que les deux méthodes (condvar base et reposant sur l'avenir) contiennent caché l'insécurité, et le premier moyen (condvar) sur les besoins du code réutilisable, je propose d'écrire une classe wrapper autour de
std::thread
. Son interface devrait être similaire à celui destd::thread
(à l'exception de ses instances doit être cessible d'autres instances de la même classe, pas destd::thread
), mais contiennent desvoid start()
méthode.Avenir-fil-wrapper
Condvar-fil-wrapper