2010-12-09 42 views
11

J'utilise Android 2.2, qui est livré avec une version de STLport. Pour une raison quelconque, il a été configuré pour ne pas être thread-safe. Cela a été fait en utilisant un #define _NOTHREADS dans un fichier d'en-tête de configuration.C++ est-il compatible avec les threads STL pour des conteneurs distincts (utilisant l'implémentation STLport)?

Lorsque j'ai construit et initialisé distincts conteneurs non partagés (par exemple, des chaînes) à partir de pthreads différents, j'obtenais corruption de la mémoire. Avec _NOTHREADS, il semble que du code de bas niveau dans STL à l'intérieur de allocator.cpp n'effectue pas de verrouillage correct. Il semble analogue à C ne fournissant pas de sécurité de fil pour malloc.

Est-ce que quelqu'un sait pourquoi STL pourrait être construit avec _NOTHREADS par défaut sur Android? En l'éteignant, je me demande s'il pourrait y avoir un effet secondaire. Une chose que je peux penser est des performances légèrement dégradées, mais je ne vois pas beaucoup de choix étant donné que j'utilise beaucoup de threads.

+0

Il peut être utile pour les personnes de répondre à votre question si vous avez donné un exemple de code qui montre le genre de chose qui mène au problème. (Je sais * je * n'ai pas l'expertise pour répondre à celle-ci, le STL n'est pas quelque chose que j'ai étudié en profondeur.) –

+0

Que voulez-vous dire par "objets accédés ..."? – LavaScornedOven

+0

Cette question a déjà été posée (voir http://stackoverflow.com/questions/4029448/thread-safety-for-stl-queue et http://stackoverflow.com/questions/1362110/is-the-c-stl- stdset-thread-safe), mais il y a encore une réponse centrale à cette question. Puisque cette version est la meilleure pour devenir ** l'endroit central pour répondre à cette question sur StackOverflow, veuillez utiliser un gros en-tête pour inclure le nom de votre implémentation et citez et liez la documentation originale. –

Répondre

5

Le SGI STL

La STL SGI est la grand-mère de toutes les autres implémentations STL.

Voir the SGI STL docs.

La mise en oeuvre du SGI STL est seulement threads en ce sens que accès simultanés à des récipients distincts sont sûre et simultanée des accès en lecture à des récipients communs sont sûrs. Si plusieurs threads accèdent à un seul conteneur et qu'au moins un thread peut potentiellement écrire, l'utilisateur est responsable de l'exclusion mutuelle entre les threads lors de l'accès au conteneur.

G ++

libstdc++ docs

Nous utilisons actuellement la définition STL SGI de sécurité des threads.

STLPort

STLPort docs

S'il vous plaît consulter le site SGI pour document détaillé sur la sécurité du fil. de base points sont:

  • accès en lecture simultanée dans le même récipient à l'intérieur des fils séparés est sûr;
  • l'accès simultané à des conteneurs distincts (non partagé entre les threads ) est sûr;
  • L'utilisateur doit fournir une synchronisation pour tous les accès si n'importe quel thread peut modifier le conteneur partagé.
+0

Des informations sur le comptage des références de chaînes? – doron

+0

Intéressant que les documents STLport disent "l'accès simultané à des conteneurs distincts (non partagés entre les threads) est sûr". Cette fonctionnalité est désactivée sur Android. – Ravi

2

Informations générales sur le C++ standard

La norme actuelle C++ ne traite pas de problèmes de concurrence du tout, donc au moins pour l'instant il n'y a pas d'exigence applicable à toutes les implémentations.

Une réponse significative ne peut vraiment s'appliquer qu'à une implémentation spécifique (STLPort, dans ce cas). STLPort est essentiellement une version de l'implémentation SGI STL originale avec des améliorations à sa portabilité, donc vous voudrez probablement commencer par le documentation sur la sécurité des threads dans la version SGI d'origine.

+0

La documentation du lien ci-dessus mentionne le problème que j'ai rencontré: "Alloc.h utilise trois primitives de verrouillage différentes en fonction de l'environnement. n'effectue aucun verrouillage en définissant _NOTHREADS. " Dans la distribution Android, _NOTHREADS a été défini. Quand je ne l'ai pas défini, les problèmes de corruption de la mémoire ont disparu. – Ravi

0

Sun WorkShop 5.0

This est un peu vieux mais très instructif. L'essentiel est que STL fournit uniquement des verrous sur les allocateurs.

Les chaînes sont toutefois référencées objets comptés, mais tout changement de leur nombre de références est fait atomiquement. Ceci n'est vrai que lors de la transmission de chaînes par valeur. Deux threads contenant la même référence à un seul objet chaîne devront effectuer leur propre verrouillage.

+0

L'implémentation linux actuelle contient les verrous. – doron

0

Lorsque vous utilisez par ex. std :: string ou des objets similaires, et les changer de différents threads, vous partagez le même objet entre les threads. Pour rendre n'importe laquelle des fonctions membres que vous pouvez appeler sur une réentrée de chaîne, cela signifierait qu'aucun autre thread ne peut affecter notre fonction mem, et notre fonction ne peut affecter aucun autre appel dans d'autres threads. La vérité est exactement le contraire, puisque vous partagez le même objet via ce pointeur, qui est implicitement donné lors de l'appel des objets membres. Pour illustrer, ce qui équivaut à cet appel

std::string a; 
a.insert(...); 

sans utiliser la syntaxe POO serait:

std::string a; 
insert(&a, ...); 

Ainsi, vous violez implicitement condition qu'aucune ressource est partagée entre les appels de fonction. Vous pouvez en voir plus here.

Espérons que cela aide.

+0

Op ne partage pas l'objet entre les threads. – Basilevs

1

Bien sûr, la raison pour laquelle il n'y a pas de ré-entrée est pour la performance: la vitesse, moins d'utilisation de la mémoire, moins d'utilisation des ressources. Vraisemblablement, c'est parce que l'hypothèse est que la plupart des programmes clients ne seront pas multithread.