9
votes

Est la fonction de fil-sécurité de SetLocale?

J'ai besoin de changer les paramètres locaux dans le fil pour analyser correctement un double avec Strtod (), j'utilise SetLocale () pour cette (C ++). Est-ce que c'est le fil sûr?

mise à jour: un autre problème. Quand j'invoque SetLocale () dans ma fonction principale (), cela n'affecte pas dans d'autres routines plus profondes. Pourquoi??? Il y a beaucoup de code, il est donc problématique d'écrire le morceau.


0 commentaires

6 Réponses :


3
votes

Vous devez consulter la documentation de toute mise en œuvre que vous utilisez. C ++ ne spécifie pas actuellement quoi que ce soit sur les threads afin de la mise en œuvre (que vous ne nous avez pas encore dit).

Par exemple, mon groupe de manche Linux pour SetLocale a l'extrait:

Cette chaîne peut être allouée en stockage statique.

qui n'indique pas absolument que c'est un danger-danger, mais je serais très méfiant. C'est probablement qui l'appelant avec NULL (c.-à-d. QUESTIONNED) serait thread-coffre-fort mais dès que vous avez un fil le modifiant, tous les paris sont éteints.

probablement le < em> la plus sûre chose à faire (en supposant que ce ne soit pas thread-coffre-fort) serait de protéger tous les appels vers SetLocale avec un mutex et avoir une fonction spéciale pour formater vos numéros le long des lignes de: xxx


1 commentaires

Les mises à jour du projet de la page MANUX plus récente contiennent absolument des informations de sécurité mt-sécurité. Faites défiler la page sur «Attributs» pour voir «MT-NAZ SAFAFE Const: locale env» qui définit la sécurité de la fonction. Ce marquage faisait partie d'une collaboration d'une année entre le projet Linux Man-pages et GLIBC pour développer un tel marquage pour une utilisation du développeur. Ensuite, 'Man 7 attributs' pour voir comment vous pouvez travailler autour de const: locale et env final de balisage pour essayer de le faire en sécurité.



2
votes

Pour C ++ 98, cela dépend du compilateur et de l'exécution de laquelle vous sélectionnez-vous et sur ce que vous entendez exactement par fil sûr.

E.g. Avec MSVC et Multi-thread-Runtime, vous devriez être en sécurité dans le sens où SetLocale est lui-même. Mais je ne pense pas que vous obtiendrez une locale par fil. Utilisez SETLOCALE pour une locale globale, pas un paramètre local par fil.

C ++ 98 ne traite pas de filetage (ou de cette matière, des bibliothèques dynamiques).


0 commentaires

7
votes

L'appel à SetLocale () peut ou non être threadsafe, mais le réglage local lui-même est pertratif, pas par thread. Cela signifie que même si vous SETLOCALE () est en sécurité ou que vous utilisez un mutex pour vous protéger, le changement mettra toujours à jour les paramètres régionaux actuels pour tous vos threads.

Il y a une alternative par threade cependant: Uselocale () . xxx

La locale utilise la référence-comptage en interne, c'est pourquoi il est sûr pour vous de la libérer une fois que vous l'avez activée avec NewLocale ().


1 commentaires

Plus précisément, le paramètre local peut être per-processus, voir msdn.microsoft.com/en-us/library/26c0tb7x.aspx



1
votes

C LANGUE DU SUPPORT DU TRANSFORME LOCALITÉ. Veuillez lire http://msdn.microsoft.com/en-us/library/ms235302 .aspx . Les principales méthodes sont les suivantes: _configthreadlocale (_enable_per_thread_locale)


0 commentaires

8
votes

dans les threads standard C ++ 11 sont maintenant une partie prise en charge de la langue. La norme appelle explicitement que les appels SetLocale () introduisent des races de données avec d'autres appels à SetLocale () ou d'appels vers des fonctions affectées par les paramètres régionaux C, y compris STRTOD (). La fonction locale :: globale () est considérée comme se comporter comme-si elle est appelée SetLocale (), elle peut également introduire une course de données (notée ci-dessous).

sur Linux avec glibc il est MT-NAZAFE (Const: Locale env) Pour que les threads appellent SetLocale () simultanément avec un argument non nulle et appelez toute autre fonction qui pourrait utiliser les paramètres régionaux globaux (course de données et comportement non défini en C11). Il est suggéré d'utiliser Uselocale () à la place qui est mt- Sûr et change uniquement les paramètres régionaux du fil d'appel. Sur Linux avec LIBSTDC ++ en C ++ Code, vous devriez éviter les paramètres régionaux :: Global (Changement de processeur) et créer un paramètre local pour l'utilisation du thread (les paramètres régionaux :: Global est MT-NUGISABLE pour les mêmes raisons que l'exécution C). Compte tenu de votre objectif d'utiliser strTOD (A API C), vous devez utiliser Uselocale ().

sur Linux à l'aide de GLIBC La fonction SETLOCALE () elle-même est MT-dangereuse, à moins que vous ne répondiez à 2 critères stricts, et comme requis par POSIX modifie les paramètres régionaux pour l'ensemble du processus. Les nouvelles pages de l'homme de Linux (une partie du Travail Red Hat et Fujitsu pour spécifier MT -safety notations pour toutes les API ) Mark SetLocale () comme "mt-dangereux const: locale env", ce qui signifie que SetLocale est MT-Safe IFF que vous gardez la constante locale (en ne la modifiant pas, il suffit de l'interroger en passant null), et si vous gardez la locale et si vous gardez la locale et Constante d'environnement (pour éviter les modifications apportées à la locale si l'argument est ""). Sur Linux à l'aide de GLIBC, vous devez utiliser USELOCALE () si vous souhaitez modifier uniquement les paramètres régionaux du fil d'appel, car il s'agit de la sécurité du MT-Safe et ne repose pas sur votre environnement en quelque sorte et Strtod utilisera les paramètres régionaux du fil. De même, tous les systèmes qui implémentent POSIX doivent fournir Uselocale () à utiliser dans un contexte de fil (MT-Safe).

OS X implémente Uselocale () afin que vous puissiez l'utiliser.

Sous Windows Utilisez _configthreadlocale Pour changer si SetLocale () fonctionne sur l'ensemble du processus ou des threads (le transforme en USelocale, ce dont vous avez besoin), mais pour le code C ++, vous devriez encore Utilisez une instance de la classe locale et évitez les paramètres régionaux :: Global .


5 commentaires

Sous Windows, vous devez utiliser les fonctions de format spécial I18N telles que GetDateFormatex au lieu de Strftime, etc. Sur MacOS, utilisez le NSFormater même lorsque vous ne faites pas de gui à cacao. Sérieusement la solution de 1980ths provoquée sur UNIX suce la terrible.


Bonne écriture. Avez-vous des références?


Ajout de références aux travaux de l'homme en amont et à la page manuelle GLIBC avec des notes de sécurité MT-Safety.


Référence ajoutée au comportement récent C ++ 11 qui inclut maintenant le filetage et les notes sur SetLocale ().


Note drôle Note: Je n'ai pas pu trouver de documentation si _configthreadlocale est en fait de sécurité. Du Docs: Si vous utilisez _configurethReadLocale pour activer un paramètre local par thread, nous vous recommandons d'appeler SetLocale ou _HsetLocale pour définir les paramètres régionaux préférés dans ce fil immédiatement après. Depuis que j'appellerais SetLocale dans des threads pour à cet effet, je devrais aussi appeler _configurethreadlocale là-bas



0
votes

Pour résoudre la deuxième partie de la question initiale:

La fonction SETLOCALE est dans la bibliothèque C (tel que défini dans un environnement C ++ par l'en-tête standard ) et son utilisation n'affectera que les routines de la bibliothèque C. Vous mentionnez C ++ dans la première partie de votre question, donc je me demande si vous vous attendez à ce que les routines C ++ prennent note des modifications de paramètres régionaux effectuées avec SetLocale . Mon expérience dit qu'ils ne le feront pas.

Les méthodes appropriées de traitement des informations sur les paramètres régionaux en C ++ sont définies par une bibliothèque spécifiée dans l'en-tête C ++ standard . Cette bibliothèque fournit le contrôle des informations sur les paramètres régionaux d'une manière compatible avec les opérations d'E / S C ++. Par exemple, vous pouvez créer un objet std :: locale avec certaines caractéristiques, puis imbue a std :: filebuf avec cet objet afin que les opérations d'E / S suivent ces caractéristiques.

Si vous exécutez dans un environnement mixte C / C ++, utilisez std :: locale :: global () - avec le bon type de paramètre, il définit également le paramètre global C La fonction de bibliothèque C SetLocale a été appelée avec LC_ALL. Cela conservera la fonctionnalité de la bibliothèque C et C ++ synchronisée.


0 commentaires