OVH Cloud OVH Cloud

Conteneurs STL et thread-safety

21 réponses
Avatar
Marc Duflot
Bonjour à tous.

Comment ça va sur fclc++ depuis les années ?

Je débute avec la programmation multi-threaded. La preuve, j'ignore même
comment on dit « multi-threaded » ou « thread-safety » en français.

J'aimerais savoir quelles sont les garanties que les conteneurs de la
bibliothèque standard se comportent de la manière attendue dans un
programme multi-threaded. Je suis bien conscient que ce n'est
certainement pas précisé dans la norme du C++ mais en pratique, qu'en
est-il des compilateurs et bibliothèques actuelles ?

Pour donner un exemple, si je fais des insertions, lectures et
suppressions dans une std::map partagé pas plusieurs threads, est-il
nécessaire de placer des locks autour de ces opérations ?

Si cela a de l'importance, mon environnement de développement est le
compilateur Intel C++ avec parallélisation avec OpenMP sur Itanium 2. La
biblio est donc celle de dinkumware, dont la documentation précise
qu'elle est thread-safe (http://www.dinkumware.com/libcpp.html) mais
sans donner plus de garantie.

Merci.

10 réponses

1 2 3
Avatar
Jean-Marc Bourguet
Marc Duflot writes:

Si cela a de l'importance, mon environnement de
développement est le compilateur Intel C++ avec
parallélisation avec OpenMP sur Itanium 2. La biblio est
donc celle de dinkumware, dont la documentation précise
qu'elle est thread-safe
(http://www.dinkumware.com/libcpp.html) mais sans donner
plus de garantie.


Seuls eux peuvent te renseigner. Il y a differents niveaux:
- au niveau le plus bas, rien n'est garanti; meme pas que
l'acces a des objets differents, que des appels à des
fonctions sans rapports dans des threads différentes se
se comportent sainement;
- à un niveau moyen, les exemples ci-dessus fonctionnent
(pour autant qu'ils soient sensés (appeler strtok dans
2 threads pose des problèmes de pertinence de
l'interface dans ce contexte), deux lectures
simultanées fonctionneraient aussi (mais pas une lecture et
une écriture)
- au niveau le plus elevé, on peut modifier un même objet
dans deux threads simultanément.

Naturellement, il y a en fait un tas de niveaux
intermédiaires... À mon avis, seul le niveau moyen tel
qu'esquissé est intéressant pour une bibliothèque standard;
tout protéger a un coût trop important sans avantages
pratiques: ce qui importe bien souvent c'est de maintenire
des invariants faisant intervenir plusieurs objets, ce qui
n'est jamais possible automatiquement. Si j'ai bonne
mémoire, c'est aussi ce que faisait SGI (il y avait une page
là-dessus dans le temps, je suppose qu'elle existe
toujours).

A+

--
Jean-Marc
FAQ de fclc++: http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ
C++ FAQ Lite en VF: http://www.ifrance.com/jlecomte/c++/c++-faq-lite/index.html
Site de usenet-fr: http://www.usenet-fr.news.eu.org

Avatar
Ahmed MOHAMED ALI
Bonjour,
Je débute avec la programmation multi-threaded. La preuve, j'ignore même
comment on dit « multi-threaded » ou « thread-safety » en français.



programmation multi-threaded --> programmation parallèle peut-être ?
thread-safety --> sûreté par rapport au threads ou plus exactement
sûreté par rapport aux flots d'exécution légèrs.Je suis preneur d'une
meilleure traduction.

J'aimerais savoir quelles sont les garanties que les conteneurs de la
bibliothèque standard se comportent de la manière attendue dans un
programme multi-threaded. Je suis bien conscient que ce n'est
certainement pas précisé dans la norme du C++ mais en pratique, qu'en
est-il des compilateurs et bibliothèques actuelles ?
Pour donner un exemple, si je fais des insertions, lectures et
suppressions dans une std::map partagé pas plusieurs threads, est-il
nécessaire de placer des locks autour de ces opérations ?


En lecture c'est "thread safe" mais en écriture il y a des précautions à
prendre.
Regarde cette page pour plus de détail.
http://www.sgi.com/tech/stl/thread_safety.html

Ahmed

"Marc Duflot" wrote in message
news:d4ahlf$n1q$
Bonjour à tous.

Comment ça va sur fclc++ depuis les années ?

Je débute avec la programmation multi-threaded. La preuve, j'ignore même
comment on dit « multi-threaded » ou « thread-safety » en français.

J'aimerais savoir quelles sont les garanties que les conteneurs de la
bibliothèque standard se comportent de la manière attendue dans un
programme multi-threaded. Je suis bien conscient que ce n'est
certainement pas précisé dans la norme du C++ mais en pratique, qu'en
est-il des compilateurs et bibliothèques actuelles ?

Pour donner un exemple, si je fais des insertions, lectures et
suppressions dans une std::map partagé pas plusieurs threads, est-il
nécessaire de placer des locks autour de ces opérations ?

Si cela a de l'importance, mon environnement de développement est le
compilateur Intel C++ avec parallélisation avec OpenMP sur Itanium 2. La
biblio est donc celle de dinkumware, dont la documentation précise
qu'elle est thread-safe (http://www.dinkumware.com/libcpp.html) mais
sans donner plus de garantie.

Merci.


Avatar
Loïc Joly
Marc Duflot writes:


Si cela a de l'importance, mon environnement de
développement est le compilateur Intel C++ avec
parallélisation avec OpenMP sur Itanium 2. La biblio est
donc celle de dinkumware, dont la documentation précise
qu'elle est thread-safe
(http://www.dinkumware.com/libcpp.html) mais sans donner
plus de garantie.



Seuls eux peuvent te renseigner. Il y a differents niveaux:
- au niveau le plus bas, rien n'est garanti; meme pas que
l'acces a des objets differents, que des appels à des
fonctions sans rapports dans des threads différentes se
se comportent sainement;
- à un niveau moyen, les exemples ci-dessus fonctionnent
(pour autant qu'ils soient sensés (appeler strtok dans
2 threads pose des problèmes de pertinence de
l'interface dans ce contexte), deux lectures
simultanées fonctionneraient aussi (mais pas une lecture et
une écriture)
- au niveau le plus elevé, on peut modifier un même objet
dans deux threads simultanément.

Naturellement, il y a en fait un tas de niveaux
intermédiaires... À mon avis, seul le niveau moyen tel
qu'esquissé est intéressant pour une bibliothèque standard;
tout protéger a un coût trop important sans avantages
pratiques: ce qui importe bien souvent c'est de maintenire
des invariants faisant intervenir plusieurs objets, ce qui
n'est jamais possible automatiquement.


J'ai bien aimé un article de sutter sur le sujet :
http://www.cuj.com/documents/s88/cuj0409i/

--
Loïc


Avatar
James Kanze
Marc Duflot wrote:

Je débute avec la programmation multi-threaded. La preuve, j'ignore même
comment on dit « multi-threaded » ou « thread-safety » en français.


Je ne crois pas qu'il y a une expression bien consacrée. Au
moins où je travaille, tout le monde dit « multi-threaded » et
« thread-safety ».

J'aimerais savoir quelles sont les garanties que les
conteneurs de la bibliothèque standard se comportent de la
manière attendue dans un programme multi-threaded.


Selon la norme, rien, parce que la norme ne connaiît pas le
concepte des threads. Il faut démander à l'implémentation.

Je suis bien conscient que ce n'est certainement pas précisé
dans la norme du C++ mais en pratique, qu'en est-il des
compilateurs et bibliothèques actuelles ?


Ça dépend. Dans la pratique, je crois que la plupart (exception
fait de g++) donne les même garanties que pour un objet de base
(ou un tableau de type C). Certaines essaient d'en donner plus,
mais en fait, ce n'est ni raisonable ni même possible. (Que
signifie même le thread-safety pour une fonction qui renvoie une
référence à un non-const ?)

Pour donner un exemple, si je fais des insertions, lectures et
suppressions dans une std::map partagé pas plusieurs threads, est-il
nécessaire de placer des locks autour de ces opérations ?


Normalement, oui.

Si cela a de l'importance, mon environnement de développement
est le compilateur Intel C++ avec parallélisation avec OpenMP
sur Itanium 2. La biblio est donc celle de dinkumware, dont la
documentation précise qu'elle est thread-safe
(http://www.dinkumware.com/libcpp.html) mais sans donner plus
de garantie.


J'imagine qu'au moins la garantie standarde, que donne toutes
les bibliothèques sauf g++. Et étant donné que plus n'a pas de
sens, probablement pas plus.

--
James Kanze mailto:
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 pl. Pierre Sémard, 78210 St.-Cyr-l'École, France +33 (0)1 30 23 00 34

Avatar
James Kanze
Ahmed MOHAMED ALI wrote:

Je débute avec la programmation multi-threaded. La preuve,
j'ignore même comment on dit « multi-threaded » ou
« thread-safety » en français.



programmation multi-threaded --> programmation parallèle
peut-être ?


Pas vraiment. On peut être multi-threaded sans être en parallel.
Un thread, c'est un fil d'exécution, si on veut. On pourrait
donc parler de la programmation à plusieurs fils d'exécution.

Si tu le fais, en revanche, je doute que tu serais aussi bien
compris que si tu parlais de la programmation « multi-threaded ».

thread-safety --> sûreté par rapport au threads ou plus
exactement sûreté par rapport aux flots d'exécution légèrs. Je
suis preneur d'une meilleure traduction.


J'aimerais bien aussi avoir un meilleur alternatif.

J'aimerais savoir quelles sont les garanties que les
conteneurs de la bibliothèque standard se comportent de la
manière attendue dans un programme multi-threaded. Je suis
bien conscient que ce n'est certainement pas précisé dans la
norme du C++ mais en pratique, qu'en est-il des compilateurs
et bibliothèques actuelles ? Pour donner un exemple, si je
fais des insertions, lectures et suppressions dans une
std::map partagé pas plusieurs threads, est-il nécessaire de
placer des locks autour de ces opérations ?



En lecture c'est "thread safe" mais en écriture il y a des
précautions à prendre.
Regarde cette page pour plus de détail.
http://www.sgi.com/tech/stl/thread_safety.html


Ce qui décrit l'implémentation SGI. G++ n'en offre pas autant,
mais je crois qu'il vaut pour toutes les autres implémentations.

--
James Kanze mailto:
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 pl. Pierre Sémard, 78210 St.-Cyr-l'École, France +33 (0)1 30 23 00 34


Avatar
James Kanze
Loïc Joly wrote:

Marc Duflot writes:



Si cela a de l'importance, mon environnement de
développement est le compilateur Intel C++ avec
parallélisation avec OpenMP sur Itanium 2. La biblio est
donc celle de dinkumware, dont la documentation précise
qu'elle est thread-safe
(http://www.dinkumware.com/libcpp.html) mais sans donner
plus de garantie.




Seuls eux peuvent te renseigner. Il y a differents niveaux:
- au niveau le plus bas, rien n'est garanti; meme pas que
l'acces a des objets differents, que des appels à des
fonctions sans rapports dans des threads différentes se
se comportent sainement;
- à un niveau moyen, les exemples ci-dessus fonctionnent
(pour autant qu'ils soient sensés (appeler strtok dans
2 threads pose des problèmes de pertinence de
l'interface dans ce contexte), deux lectures
simultanées fonctionneraient aussi (mais pas une lecture et
une écriture)
- au niveau le plus elevé, on peut modifier un même objet
dans deux threads simultanément.



Naturellement, il y a en fait un tas de niveaux
intermédiaires... À mon avis, seul le niveau moyen tel
qu'esquissé est intéressant pour une bibliothèque standard;
tout protéger a un coût trop important sans avantages
pratiques: ce qui importe bien souvent c'est de maintenire
des invariants faisant intervenir plusieurs objets, ce qui
n'est jamais possible automatiquement.



J'ai bien aimé un article de sutter sur le sujet :
http://www.cuj.com/documents/s88/cuj0409i/


Sauf que la définition de la thread-safety que Herb utilise dans
l'article ne correspond pas à une des catégories ci-dessus, ni à
celle de Posix. Et en plus, il cherche à l'éclairer au moyen
d'un problème assez subtile (COW).

Le niveau moyen de Jean-Marc correspond à la garantie Posix.
C'est à peu près le maximum qu'on peut raisonablement garantir
pour une collection qui laisse échapper des références non-const
à son implémentation, et c'est à peu près le minimum qu'il faut
pour pouvoir s'en servir raisonablement dans un contexte
multi-threaded.

--
James Kanze mailto:
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 pl. Pierre Sémard, 78210 St.-Cyr-l'École, France +33 (0)1 30 23 00 34



Avatar
Gabriel Dos Reis
James Kanze writes:

| Ça dépend. Dans la pratique, je crois que la plupart (exception
| fait de g++) donne les même garanties que pour un objet de base
| (ou un tableau de type C).

Puisque tu répètes ceci dans tout ce fil, sans que je puisse
comprendre ce que tu voulais dire, je serais heureux d'en voir un
élaboration plus claire.

-- Gaby
Avatar
James Kanze
Loïc Joly wrote:

J'ai bien aimé un article de sutter sur le sujet :
http://www.cuj.com/documents/s88/cuj0409i/


Je signale aussi en passant que l'article a été le sujet d'une
très longue discussion dans comp.lang.c++.moderated, voir :

http://groups.google.fr/groups?hl=fr&lr=&c2coff=1&threadmÖ652001.0409160415.4142660a%40posting.google.com&rnum=1&prev=/groups%3Fq%3Dcow%2Bmulti-threaded%2Bsutter%26hl%3Dfr%26lr%3D%26group%3Dcomp.lang.c%252B%252B.moderated%26c2coff%3D1%26selm%3Dd6652001.0409160415.4142660a%2540posting.google.com%26rnum%3D1

(Si le news abîme la référence ci-dessus, chercher « cow
multi-threaded sutter » en restreignant la recherche au groupe
comp.lang.c++.moderated.

--
James Kanze mailto:
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 pl. Pierre Sémard, 78210 St.-Cyr-l'École, France +33 (0)1 30 23 00 34

Avatar
James Kanze
Gabriel Dos Reis wrote:
James Kanze writes:


| Ça dépend. Dans la pratique, je crois que la plupart
| (exception fait de g++) donne les même garanties que pour un
| objet de base (ou un tableau de type C).


Puisque tu répètes ceci dans tout ce fil, sans que je puisse
comprendre ce que tu voulais dire, je serais heureux d'en voir
un élaboration plus claire.


Il faudrait que j'en fasse une FAQ -- c'est la troisième fois ce
mois-ci qu'on me le démande:-).

Sans entrer dans tous les détails en ce qui concerne où il y a
le problème dans le code (je te les fournirais si tu veux, mais
ça risque d'ennuyer les autres ici, étant donné que c'est du
propre à g++), le problème est simple : si j'ai une instance de
std::string que je veux accéder depuis plusieurs threads, il
faut que je synchronise les accès avec g++, même si aucun des
accès ne modifie la chaîne.

Je suis prèsque sûr d'avoir vue quelque part dans la
documentation g++ que c'est exprès -- que g++ ne veut pas donner
d'avantage de garanties. Ce qui est dommage, parce que Posix,
lui, en exige plus -- selon Posix, je peux accéder à un objet
depuis plusieurs threads sans synchronisation externe dans la
mésure qu'aucun thread ne modifie l'objet.

--
James Kanze mailto:
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 pl. Pierre Sémard, 78210 St.-Cyr-l'École, France +33 (0)1 30 23 00 34

Avatar
Gabriel Dos Reis
James Kanze writes:

| Gabriel Dos Reis wrote:
| > James Kanze writes:
|
| > | Ça dépend. Dans la pratique, je crois que la plupart
| > | (exception fait de g++) donne les même garanties que pour un
| > | objet de base (ou un tableau de type C).
|
| > Puisque tu répètes ceci dans tout ce fil, sans que je puisse
| > comprendre ce que tu voulais dire, je serais heureux d'en voir
| > un élaboration plus claire.
|
| Il faudrait que j'en fasse une FAQ -- c'est la troisième fois ce
| mois-ci qu'on me le démande:-).

désolé de pas suivre tes écrits à la virgules près ces derniers temps
-- il y a tellement de monde qui demande qu'on les lise tous les jours
que cela devient un vrai embouteillage.

| Sans entrer dans tous les détails en ce qui concerne où il y a
| le problème dans le code (je te les fournirais si tu veux, mais
| ça risque d'ennuyer les autres ici, étant donné que c'est du
| propre à g++),

Puisque tu as jugé que cela n'ennuyerait pas les autres de repéter
cette remarque encore et encore, je crois qu'il est tout à fait
bienvenu et souhaité que tu donnes ces problèmes ici. On pourra
toujours arrêté si cela devient du hardcore.

| le problème est simple : si j'ai une instance de
| std::string que je veux accéder depuis plusieurs threads, il
| faut que je synchronise les accès avec g++, même si aucun des
| accès ne modifie la chaîne.

???

Pas plus tard qu'hier, j'ai reçu un mail (avec copie à d'autres
maintainers de la GNU libstdc++ ainsi que Nathan Myers, l'auteur
principal de std::string dans GNU libstdc++, et en CC: de ce message)
reflétant des inquiétudes (FUD ?) d'un utilisateur qui aurait lu des
messages récents sur les newsgroupes alléguant des propos proches de
ceux que tu viens de tenir -- je ne sais pas s'ils viennent de toi ou
non, donc ne saute pas au plafond avant d'avour lu la suite.
La réponse qu'il a reçue est en très grand contraste avec ce que tu
affirmes, alors j'apprecierais tu nous donnes plus de précisions.

| Je suis prèsque sûr d'avoir vue quelque part dans la
| documentation g++ que c'est exprès -- que g++ ne veut pas donner
| d'avantage de garanties. Ce qui est dommage, parce que Posix,
| lui, en exige plus -- selon Posix, je peux accéder à un objet
| depuis plusieurs threads sans synchronisation externe dans la
| mésure qu'aucun thread ne modifie l'objet.

Et tu as fait des tests qui ont montré que cette guarantie ne tien pas ?
Si tu l'as fait, je serai (et sûrement Nathan Myers aussi) curieux
d'avoir des données plus précises -- au delà d'un flou nébuleux.
(Je reconnais d'avance que faire des tests pour des programmes
multi-thread n'est pas facile).

-- Gaby
1 2 3