Motivation: la raison pour laquelle je pense que c'est parce que mon chef de projet de génie pense que le boost est une autre dépendance et que c'est horrible parce que "vous en dépendez" (j'ai essayé d'expliquer la qualité du boost, puis j'ai abandonné au bout d'un moment :( La plus petite raison pour laquelle je voudrais le faire est que j’aimerais apprendre les fonctionnalités de c ++ 11, car les gens commenceront à écrire du code dans celui-ci.
#include<thread> #include<mutex>
et augmenter les équivalents?P.S. J'utilise GCC alors les en-têtes sont là.
Il existe plusieurs différences entre Boost.Thread et la bibliothèque de threads standard C++ 11:
std::async
, Mais pas Boostboost::shared_mutex
Pour le verrouillage à plusieurs lecteurs/un seul auteur. L’analogue std::shared_timed_mutex
N’est disponible que depuis C++ 14 ( N3891 ), tandis que std::shared_mutex
N’est disponible que depuis C++ 17 ( N4508 =).boost::unique_future
Vs std::future
)std::thread
Est différente de boost::thread
--- Boost utilise boost::bind
, Ce qui nécessite des arguments copiables. std::thread
Permet aux types de déplacement uniquement tels que std::unique_ptr
D'être transmis en tant qu'arguments. En raison de l'utilisation de boost::bind
, La sémantique des espaces réservés tels que _1
Dans les expressions de liaison imbriquées peut également être différente.join()
ou detach()
, le destructeur boost::thread
Et l'opérateur d'affectation appellent detach()
sur l'objet de thread en cours de destruction/assigné à. Avec un objet C++ 11 std::thread
, Il en résultera un appel à std::terminate()
et un abandon de l'application.Pour clarifier le point concernant les paramètres de déplacement uniquement, ce qui suit est valide C++ 11 et transfère la propriété du int
du temporaire std::unique_ptr
Au paramètre de f1
lorsque le nouveau thread est démarré. Cependant, si vous utilisez boost::thread
, Cela ne fonctionnera pas, car il utilise boost::bind
En interne et std::unique_ptr
Ne peut pas être copié. Il existe également un bogue dans la bibliothèque de threads C++ 11 fournie avec GCC qui empêche ce fonctionnement, car il utilise également std::bind
Dans son implémentation.
void f1(std::unique_ptr<int>);
std::thread t1(f1,std::unique_ptr<int>(new int(42)));
Si vous utilisez Boost, vous pouvez probablement passer aux threads C++ 11 de manière relativement simple si votre compilateur le supporte (par exemple, les versions récentes de GCC sur Linux ont une implémentation presque complète de la bibliothèque de threads C++ 11 disponible dans -std=c++0x
).
Si votre compilateur ne prend pas en charge les threads C++ 11, vous pourrez peut-être obtenir une implémentation tierce telle que Just :: Thread , mais il s'agit toujours d'une dépendance.
std::thread
est largement inspiré de boost::thread
, avec quelques différences :
- la sémantique non optimisée de one-handle-maps-to-one-os-thread de boost est conservée. Mais ce fil est mobile pour permettre le retour du fil des fonctions d'usine et son placement dans des conteneurs.
- Cette proposition ajoute l'annulation à la
boost::thread
, qui est une complication significative. Cette modification a un impact important non seulement sur les threads, mais également sur le reste de la bibliothèque de threads C++. On pense que ce changement important est justifiable en raison des avantages.
- Le destructeur de threads doit maintenant appeler cancel avant de détacher pour éviter une fuite accidentelle de threads enfants lorsque les threads parents sont annulés.
- Un membre de détachement explicite est maintenant requis pour permettre le détachement sans annuler.
- Les concepts de handle de thread et d'identité de thread ont été séparés en deux classes (il s'agit de la même classe dans
boost::thread
). Cela facilite la manipulation et le stockage de l'identité du fil.- La possibilité de créer un identifiant de thread dont la comparaison est garantie à aucun autre thread pouvant être joint n'a été ajoutée (
boost::thread
n'a pas cela). C'est pratique pour le code qui veut savoir s'il est exécuté par le même thread qu'un appel précédent (les mutex récursifs en sont un exemple concret).- Il existe une "porte dérobée" pour obtenir le descripteur de thread natif afin que les clients puissent manipuler les threads à l'aide du système d'exploitation sous-jacent, le cas échéant.
C’est à partir de 2007, certains points ne sont donc plus valides: boost::thread
a un native_handle
fonctionne maintenant et, comme le soulignent les commentateurs, std::thread
n'a plus d'annulation.
Je n'ai trouvé aucune différence significative entre boost::mutex
et std::mutex
.
cas d'entreprise
Si vous écrivez un logiciel pour une entreprise devant fonctionner sur une grande variété de systèmes d’exploitation et, par conséquent, compiler avec divers compilateurs et versions de compilateur (en particulier des versions relativement anciennes) sur ces systèmes d’exploitation, ma suggestion est de rester à l’écart. C++ 11 tout à fait pour le moment. Cela signifie que vous ne pouvez pas utiliser std::thread
, et je recommanderais d'utiliser boost::thread
.
Cas de démarrage Basic/Tech
Si vous écrivez pour un ou deux systèmes d’exploitation, vous êtes certain de ne jamais avoir besoin de compiler avec un compilateur moderne qui supporte principalement C++ 11 (par exemple, VS2015, GCC 5.3, Xcode 7), et vous n’êtes pas déjà dépendant de la bibliothèque de boost, puis std::thread
pourrait être une bonne option.
Mon expérience
Personnellement, je préfère les bibliothèques renforcées, fortement utilisées, très compatibles et très cohérentes telles que boost par rapport à une alternative très moderne. Cela est particulièrement vrai pour les sujets de programmation complexes tels que les threads. En outre, j'ai longtemps connu un grand succès avec boost::thread
(et boost en général) dans une vaste gamme d’environnements, de compilateurs, de modèles de threads, etc. Lorsque c’est mon choix, je choisis boost.
Il y a une raison pour ne pas migrer vers std::thread
.
Si vous utilisez des liens statiques, std::thread
devient inutilisable à cause de ces bogues/caractéristiques de gcc:
À savoir, si vous appelez std::thread::detach
ou std::thread::join
cela entraînera une exception ou un crash, alors que boost::thread
fonctionne bien dans ces cas.
Avec Visual Studio 2013, le std::mutex
semble se comporter différemment du boost::mutex
, ce qui m'a causé quelques problèmes (voir cette question ).
Les autres réponses ici donnent un très bon aperçu des différences en général. Cependant, il existe plusieurs problèmes avec std::shared_mutex
Que boost résout.
Mutices améliorables. Ceux-ci sont absents de std::thread
. Ils permettent à un lecteur d'être mis à niveau vers un rédacteur sans permettre à aucun autre rédacteur d'entrer avant vous . Celles-ci vous permettent d'effectuer des opérations telles que le prétraitement d'un calcul volumineux (par exemple, la réindexation d'une structure de données) en mode lecture, puis la mise à niveau en écriture pour appliquer la réindexation tout en maintenant le verrou en écriture pendant une courte période.
Justice. Si vous avez une activité de lecture constante avec un std::shared_mutex
, Vos rédacteurs seront verrouillés pour une durée indéterminée. En effet, si un autre lecteur se présente, il aura toujours la priorité. Avec boost:shared_mutex
, La priorité sera donnée à tous les threads .(1) Ni les lecteurs ni les écrivains ne seront affamés.
Le problème, c’est que si vous avez un système à très haut débit, sans temps d’immobilisation ni conflit important, std::shared_mutex
Ne fonctionnera jamais pour vous sans la construction manuelle d’un système de priorité. boost::shared_mutex
Fonctionnera immédiatement, mais vous aurez peut-être besoin de le modifier dans certains cas. Je dirais que le comportement de std::shared_mutex
Est un bogue latent en attente dans la plupart des codes qui l'utilisent.
(1)Le algorithme qu'il utilise est basé sur le planificateur de threads du système d'exploitation. D'après mon expérience, lorsque les lectures sont saturées, les pauses sont plus longues (lors de l'obtention d'un verrou en écriture) sous Windows que sous OSX/Linux.
J'ai essayé d'utiliser shared_ptr à partir de std au lieu de boost et j'ai trouvé un bogue dans l'implémentation gcc de cette classe. Mon application se bloquait à cause d'un destructeur appelé deux fois (cette classe devrait être thread-safe et ne devrait pas générer de tels problèmes). Après avoir déplacé boost :: shared_ptr, tous les problèmes ont disparu. Les implémentations actuelles de C++ 11 ne sont toujours pas mûres.
Boost a également plus de fonctionnalités. Par exemple, l'en-tête dans la version std ne fournit pas de sérialiseur à un flux (c'est-à-dire cout << durée). Boost a beaucoup de bibliothèques qui utilisent ses propres équivalents, etc., mais ne coopèrent pas avec les versions std.
Pour résumer, si vous avez déjà une application écrite avec boost, il est préférable de conserver votre code tel quel au lieu de faire des efforts pour passer à la norme C++ 11.