Motivation: la raison pour laquelle je considère que c'est 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é après un certain temps :( Une raison plus petite pour laquelle j'aimerais le faire est que j'aimerais apprendre les fonctionnalités de C ++ 11, car les gens commenceront à écrire du code. Donc:
- Existe-t-il un mappage 1: 1 entre
#include<thread> #include<mutex>
et les équivalents boost? - Considérez-vous une bonne idée de remplacer les éléments boost par des éléments c ++ 11
. Mon utilisation est primitive, mais y a-t-il des exemples où std n'offre pas ce que fait le boost? Ou (blasphème) vice versa?
PS J'utilise GCC donc les en-têtes sont là.
Réponses:
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 de plusieurs lecteurs / écriture unique. L'analoguestd::shared_timed_mutex
n'est disponible que depuis C ++ 14 ( N3891 ), alors qu'ilstd::shared_mutex
n'est disponible que depuis C ++ 17 ( N4508 ).boost::unique_future
vsstd::future
)std::thread
est différente de celle utilisée parboost::thread
--- Boostboost::bind
, qui nécessite des arguments copiables.std::thread
autorise les types de déplacement uniquement tels questd::unique_ptr
d'être passés comme arguments. En raison de l'utilisation deboost::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()
oudetach()
alors leboost::thread
destructeur et l'opérateur d'affectation appellerontdetach()
l'objet thread en cours de destruction / assignation. Avec unstd::thread
objet C ++ 11 , cela entraînera un appel àstd::terminate()
et abandonnera l'application.Pour clarifier le point sur les paramètres de déplacement uniquement, ce qui suit est C ++ 11 valide et transfère la propriété du
int
du temporairestd::unique_ptr
au paramètre duf1
moment où le nouveau thread est démarré. Cependant, si vous utilisez,boost::thread
cela ne fonctionnera pas, car il utilise enboost::bind
interne etstd::unique_ptr
ne peut pas être copié. Il y a aussi un bogue dans la bibliothèque de threads C ++ 11 fournie avec GCC qui empêche cela de fonctionner, comme il l'utilise égalementstd::bind
dans l'implémentation.Si vous utilisez Boost, vous pouvez probablement passer aux threads C ++ 11 relativement facilement si votre compilateur le prend en charge (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 en
-std=c++0x
mode).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.
la source
lock
/unlock
pour les écrivains contre «lock_shared / unlock_shared» pour les lecteurs). Plusieurs lecteurs peuvent appeler lock_shared sans blocage, tant qu'aucun écrivain ne l'utilise.shared_mutex
documents se trouvent sur boost.org/doc/libs/1_47_0/doc/html/thread/… . Vous verrouillez le mutex comme partagé ou exclusif, puis utilisez la fonction de déverrouillage correspondante. Vous pouvez également utiliser les types RAII pour ce faire (shared_lock
prend un verrou de lecture partagélock_guard
etunique_lock
prend un verrou exclusif). J'ai essayé de clarifier le point sur les types de mouvement uniquement.try_scoped_lock
fonctionnalité est couverte parstd::unique_lock
. Il existe un constructeur qui prend un mutex etstd::try_to_lock
, et appellera ensuitetry_lock()
le mutex plutôt quelock()
. Voir stdthread.co.uk/doc/headers/mutex/unique_lock/…std::thread
est largement modélisé d'aprèsboost::thread
, avec quelques différences :Cela date de 2007, donc certains points ne sont plus valides:
boost::thread
a unenative_handle
fonction maintenant, et, comme le soulignent les commentateurs,std::thread
n'a plus d'annulation.Je n'ai pas trouvé de différences significatives entre
boost::mutex
etstd::mutex
.la source
std::thread
n'a pas d'annulation; c'estboost::thread
ça!interrupt()
pour boost :: thread? Il semble également que ce soit une proposition originale, qui a changé depuis 2007.Il y a une raison de ne pas migrer vers
std::thread
.Si vous utilisez la liaison statique,
std::thread
devient inutilisable en raison de ces bogues / fonctionnalités gcc:À savoir, si vous appelez
std::thread::detach
oustd::thread::join
cela entraînera une exception ou un crash, alors que celaboost::thread
fonctionne bien dans ces cas.la source
libpthread.a
. Êtes-vous absolument sûr de ce que vous dites?Wl,--whole-archive -lpthread -Wl,--no-whole-archive
, voir cette réponse par exemple stackoverflow.com/a/23504509/72178 . Mais ce n'est pas un moyen très simple d'établir un lien aveclibpthread.a
et également considéré comme une mauvaise idée.Cas d'entreprise
Si vous écrivez un logiciel pour l'entreprise qui doit fonctionner sur une variété modérée à grande de systèmes d'exploitation et, par conséquent, construire avec une variété de compilateurs et de versions de compilateurs (en particulier les versions relativement anciennes) sur ces systèmes d'exploitation, ma suggestion est de rester à l'écart de C ++ 11 au total pour le moment. Cela signifie que vous ne pouvez pas utiliser
std::thread
, et je recommanderais d'utiliserboost::thread
.Cas de démarrage de base / technique
Si vous écrivez pour un ou deux systèmes d'exploitation, vous savez avec certitude que vous n'aurez jamais besoin de construire qu'avec un compilateur moderne qui prend principalement en charge C ++ 11 (par exemple VS2015, GCC 5.3, Xcode 7), et vous ne l'êtes pas déjà dépend de la bibliothèque de boost, alors
std::thread
pourrait être une bonne option.Mon expérience
Personnellement, je préfère les bibliothèques renforcées, très utilisées, hautement 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 compliqués tels que le threading. De plus, j'ai longtemps connu un grand succès avec
boost::thread
(et un boost en général) à travers une vaste gamme d'environnements, de compilateurs, de modèles de threading, etc. Quand c'est mon choix, je choisis boost.la source
Avec Visual Studio 2013, le
std::mutex
semble se comporter différemment duboost::mutex
, ce qui m'a causé quelques problèmes (voir cette question ).la source
En ce qui concerne std :: shared_mutex ajouté dans C ++ 17
Les autres réponses ici donnent un très bon aperçu des différences en général. Cependant, il y a plusieurs problèmes avec
std::shared_mutex
ce boost résout.Mutices évolutifs. Ceux-ci sont absents de
std::thread
. Ils permettent à un lecteur d'être mis à niveau vers un écrivain sans permettre à d'autres écrivains d'entrer avant vous . Ceux-ci vous permettent de faire des choses comme pré-traiter un gros calcul (par exemple, réindexer une structure de données) en mode lecture, puis mettre à niveau en écriture pour appliquer la réindexation tout en maintenant le verrou d'écriture pendant une courte période.Justice. Si vous avez une activité de lecture constante avec a
std::shared_mutex
, vos rédacteurs seront verrouillés indéfiniment. En effet, si un autre lecteur arrive, il aura toujours la priorité. Avecboost:shared_mutex
, tous les threads auront finalement la priorité. (1) Ni les lecteurs ni les écrivains ne seront affamés.Le tl; dr de ceci est que si vous avez un système à très haut débit sans temps d'arrêt et très controversé,
std::shared_mutex
ne fonctionnera jamais pour vous sans créer manuellement un système de priorité par-dessus.boost::shared_mutex
fonctionnera immédiatement, même si vous devrez peut-être le bricoler dans certains cas. Je dirais questd::shared_mutex
le comportement de est un bug latent qui attend de se produire dans la plupart des codes qui l'utilisent.(1) L' algorithme réel 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, il y a des pauses plus longues (lors de l'obtention d'un verrou d'écriture) sous Windows que sous OSX / Linux.
la source
J'ai essayé d'utiliser shared_ptr de std au lieu de boost et j'ai en fait trouvé un bogue dans l'implémentation gcc de cette classe. Mon application plantait à cause du destructeur appelé deux fois (cette classe devrait être thread-safe et ne devrait pas générer de tels problèmes). Après être passé à boost :: shared_ptr, tous les problèmes ont disparu. Les implémentations actuelles de C ++ 11 ne sont toujours pas matures.
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 de nombreuses 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 à l'aide de boost, il est plus sûr de garder votre code tel quel au lieu de faire des efforts pour passer au standard C ++ 11.
la source
shared_ptr
destructeur n'a pas besoin d'être thread-safe, c'est un comportement indéfini pour qu'un thread accède à un objet pendant qu'un autre thread le détruit. Si vous pensez avoir trouvé un bogue dans shared_ptr de GCC, veuillez le signaler , sinon, selon la balance des probabilités, vous l'utilisez mal.