124 votes

Va async(lancement::async) en C++11 pour des pools de threads obsolète pour éviter de coûteuses de création de thread?

Il est vaguement lié à cette question: Êtes std::thread pool en C++11?. Bien que la question est différente, l'intention est la même:

Question 1: Est-il encore un sens à l'utilisation de votre propre (ou de la 3e partie de la bibliothèque) des pools de threads pour éviter de coûteux de création de thread?

La conclusion dans l'autre question est que vous ne pouvez pas compter sur std::thread à être mis en commun (il peut ou peut être pas). Toutefois, std::async(launch::async) semble avoir beaucoup plus de chances d'être mises en commun.

Il ne pense pas qu'il y est forcé par la norme, mais à mon humble avis je m'attends à ce que tout bon C++11 implémentations serait d'utiliser du fil de mise en commun si la création de threads est lente. Uniquement sur les plates-formes où il est peu coûteux de créer un nouveau fil de discussion, je m'attends à ce qu'ils ont toujours générer un nouveau thread.

Question 2: C'est juste ce que je pense, mais je n'ai pas faits pour le prouver. Je peut très bien se tromper. Est-ce une supposition?

Enfin, ici, j'ai fourni un exemple de code qui montre d'abord comment je pense que la création de threads peuvent être exprimées en async(launch::async):

Exemple 1:

 thread t([]{ f(); });
 // ...
 t.join();

devient

 auto future = async(launch::async, []{ f(); });
 // ...
 future.wait();

Exemple 2: Fire and forget fil

 thread([]{ f(); }).detach();

devient

 // a bit clumsy...
 auto dummy = async(launch::async, []{ f(); });

 // ... but I hope soon it can be simplified to
 async(launch::async, []{ f(); });

Questin 3: préférez-vous l' async versions de l' thread versions?


Le reste n'est plus une partie de la question, mais seulement pour la clarification:

Pourquoi faut-il le retour de la valeur affectée à une variable fictive?

Malheureusement, l'actuel C++11 standard des forces de l'acquisition de la valeur de retour de l' std::async, sinon le destructeur est exécutée, ce qui bloque jusqu'à ce que l'action se termine. Il est considéré comme une erreur dans la norme (p. ex., par Herb Sutter).

Cet exemple de l' cppreference.com l'illustre bien:

{
  std::async(std::launch::async, []{ f(); });
  std::async(std::launch::async, []{ g(); });  // does not run until f() completes
}

Une autre précision:

Je sais que les pools de threads peuvent avoir d'autres legimate utilise, mais dans cette question, je ne suis qu'intéressantes, à l'aspect d'éviter de coûteuses de création de thread coûts.

Je pense qu'il y a encore des situations où les pools de threads sont très utiles, surtout si vous avez besoin de plus de contrôle sur les ressources. Par exemple, un serveur peut décider de traiter qu'un nombre fixe de demandes simulatenously pour garantir des temps de réponse rapide et d'accroître la prévisibilité de l'utilisation de la mémoire. Les pools de threads doit être fine, ici.

Ces variables peuvent aussi être un argument pour votre propre pools de threads, mais je ne suis pas sûr de savoir si c'est conditions dans la pratique:

  • La création d'un nouveau thread avec std::thread démarre sans initialisé les variables locales de thread. Peut-être que ce n'est pas ce que vous voulez.
  • Dans les fils engendré par async, il est peu claire pour moi parce que le fil aurait pu être réutilisés. De ma compréhension, ces variables ne sont pas garantis pour être remises à zéro, mais je me trompe peut-être.
  • À l'aide de votre propre (de taille fixe) des pools de threads, d'autre part, vous donne le plein contrôle si vous en avez vraiment besoin.

61voto

Omnifarious Points 25666

Question 1:

Je sais que sous Linux création de thread a été fait très bon marché. Et donc il n'y a pas beaucoup de raison d'avoir des pools de threads pour éviter la création de thread coûts dans Linux.

Aussi, je ne pense pas que la bibliothèque standard de fabrication du fil création plutôt transparent touche vraiment ce calcul beaucoup. Elle permet simplement de "sembler" plus rapide et plus facile de lancer un thread. Il dépend plus de votre système d'exploitation que sur le C++. À mon humble avis, les Os ont beaucoup de raisons pour lesquelles ils devraient faire de la création de threads aussi bon marché que possible. Auto-parallélisation des boucles en est un exemple.

Question 2:

Oui, en gros ce "implicitement' lance un thread. Mais vraiment, c'est encore tout à fait évident que ce qui se passe. Donc je ne pense pas vraiment que le mot implicitement est un très bon mot.

Question 3:

Personnellement, j'aime thread lance d'être explicite. Je place beaucoup de valeur dans les îles où vous pouvez garantir l'accès série. Sinon vous vous retrouvez avec mutable état que vous avez toujours être l'enveloppant d'un mutex autour de quelque part et de se souvenir de l'utiliser.

J'ai aimé la file d'attente de travail modèle beaucoup mieux que le "futur" de modèle, car il y a des "îles de la série" mentir autour de sorte que vous pouvez gérer plus efficacement mutable état.

Mais vraiment, ça dépend exactement ce que vous faites.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X