2013-03-09 4 views
7

Je lis le modèle de mémoire C++ défini dans n3485 et il parle de libération/acquisition sémantique, qui d'après ce que je comprends, et aussi des définitions given in this blog:Release/acquisition sémantique WRT std :: mutex

Acquérir la sémantique est une propriété qui ne peut s'appliquer qu'aux opérations lues à partir de la mémoire partagée, qu'il s'agisse d'opérations de lecture-modification-écriture ou de charges simples. L'opération est alors considérée comme une lecture-acquisition. Acquérir la sémantique empêche le réordonnancement de la mémoire de l'acquisition en lecture avec toute opération de lecture ou d'écriture qui la suit dans l'ordre du programme.

sémantique de sortie est une propriété qui ne peut appliquer aux opérations qui écrivent à mémoire partagée, si ce sont des opérations de lecture-modification-écriture ou les magasins ordinaires. L'opération est alors considérée comme une écriture-libération. La sémantique de publication empêche le réordonnancement de la mémoire en écriture avec toute opération de lecture ou d'écriture qui la précède dans l'ordre du programme.

va empêcher réordonnancement de lecture/écriture avant ou après la lecture en cours/écriture étant fait. Le premier (Acquérir) s'assurera que la lecture en cours n'est pas réorganisée avec une lecture/écriture venant après, la dernière (version) s'assurera que l'écriture courante n'est pas réordonnée avec les opérations de lecture/écriture qui viennent avant il.

Maintenant, peut-on dire que std::mutex::lock aura Acquire sémantique et que std::mutex::unlock a essentiellement version sémantique?

Dans la norme je peux trouver cette application de l'article

30.4.1.2 types Mutex [thread.mutex.requirements.mutex]

11 Synchronisation: Avant unlock() opérations sur le même objet doit synchroniser avec (1.10) cette opération.

D'après ce que je comprends Synchronize cependant, avec n'est pas explicitement défini dans la norme, mais il semble être un type de se produit avant relation regardant deux déclarations en cours d'évaluation entre deux fils différents, de mon compréhension de la sémantique Acquisition/Libération, cela a plus à voir avec le réordonnancement de la mémoire. synchroniser avec pourrait également être appelé libérer/acquérir sémantique?

Alors, est-ce que la sémantique de libération/acquisition s'applique non seulement à la réorganisation des opérations de chargement/stockage, mais aussi à l'entrelacement intra-thread des opérations?

Dans la section standard sur le modèle de mémoire, il parle principalement des relations ordonnées en termes d'entrelacement de deux threads. Cela laisse ouverte à l'interprétation quant à savoir si cela s'applique également à l'ordre de la mémoire.

Quelqu'un peut-il clarifier?

+2

"Synchroniser avec" est défini dans [intro.multithread], 1.10, paragraphe 8. –

+0

@PeteBecker: Vrai, mais ce qui y est écrit ne sonne pas vraiment comme une "définition": "* Certains appels de bibliothèque se synchronisent avec d'autres par exemple, une sortie de magasin atomique se synchronise avec une acquisition de charge qui prend sa valeur dans le magasin (29.3). * "Des mots comme" certain "et" par exemple "ne sont pas très formels. –

+0

@AndyProwl - tu as raison, c'est un peu flou. Pas à cause de "certains", ce qui est une manière courte de dire "certains mais pas tous", mais parce que cela ne dit pas tout à fait ce que cela signifie. Lorsque les exigences de la bibliothèque indiquent qu'une opération "se synchronise" avec une autre opération, cela introduit un ordre qui devient une partie de la relation "inter-thread arrive avant". Donc, il n'y a pas un seul endroit qui définit formellement "synchronise avec". C'est une définition distribuée: partout où la spécification de la bibliothèque dit que cela arrive, c'est là où ça se passe. –

Répondre

6

Maintenant, peut-on dire que std :: mutex :: lock aura une sémantique acquise et que std :: mutex :: unlock aura essentiellement une sémantique de libération?

Oui, c'est correct.

D'après ce que je comprends se synchronisent avec n'est pas explicitement défini dans la norme

Eh bien, en théorie Paragraphe 1.10/8 est probablement destiné à donner la définition de se synchronise avec:

Certains appels de bibliothèque se synchronisent avec d'autres appels de bibliothèque exécutés par un autre thread. Par exemple, une sortie de magasin atomique se synchronise avec une acquisition de charge qui prend sa valeur dans le magasin (29.3). [Note: ...]

D'autre part, cela ne semble pas être une définition très formelle. Cependant, un meilleur, mais une implicite est indirectement donnée au paragraphe 1.10/10:

Une Une évaluation est dépendance commandé avant une évaluation B si

- A effectue une opération de séparation sur un atomique objet M, et, dans un autre thread, B exécute une consomment opération sur M et lit une valeur écrite par aucun effet secondaire dans la séquence de libération dirigé par a, ou

- pour une évaluation X, a est la dépendance ordonnée avant que X et X portent une dépendance à B.

[Note: La relation "is dependency-ordered before" est analogue à "synchronizes with", mais utilise release/- consomme à la place de release/acquire. -end ndlr]

Depuis la « est analogue à » relation est le plus souvent symétrique, je dirais que la définition ci-dessus « est-dépendance ordonnée avant » fournit indirectement une définition de " se synchronise également avec "- bien que vous puissiez objecter correctement que les notes ne sont pas normatives; encore, cela semble être la définition voulue.

Mon intuition de l'synchronise avec relation est qu'il se produit entre une opération d'écriture (atomique) réalisée par un fil qui mémorise une certaine valeur et la première opération (atomique) qui lit cette valeur. Cette opération pourrait aussi bien être dans le même fil.

Si les deux opérations se trouvent sur des threads différents, la relation synchronizes-with établit un ordre de threads sur les opérations.

Dans la norme je peux trouver cette application de l'article

30.4.1.2 types Mutex [thread.mutex.requirements.mutex]

11 Synchronisation: Avant unlock() opérations sur le même objet doit synchroniser avec (1.10) cette opération.

Pour moi, cela semble compatible avec l'interprétation donnée ci-dessus. Une opération avec une sémantique de libération (déverrouillage, stockage) se synchronisera avec une opération de sémantique acquise (verrouiller, charger). Cependant, d'après ce que je comprends de la sémantique Acquisition/Libération, cela a plus à voir avec le réordonnancement de la mémoire. synchroniser avec pourrait aussi être appelé libération/acquérir sémantique? Libérer et acquérir une sémantique décrivant la nature de certaines opérations; la relation synchronise-with est (en effet) une relation qui est établie entre des opérations qui ont une sémantique d'acquisition ou de libération, d'une manière bien définie.

Donc dans un sens, synchronise avec est une conséquence de la sémantique de ces opérations, et nous utilisons cette sémantique pour obtenir l'ordre correct des instructions et de la contrainte du réordonnancement possible que le CPU ou le compilateur effectuer.

+1

Ainsi, un mutex agit comme une clôture, mais la seule différence est qu'avec une clôture, plusieurs threads peuvent toujours exécuter le code simultanément, alors qu'un mutex rend ce code mutuellement exclusif, non? –

+2

@TonyTheLion: J'apprends toujours ce genre de choses (plus ou moins comme vous je suppose) et j'ai écrit cette réponse sans beaucoup de connaissances formelles, pour essayer de compléter votre compréhension partielle avec ma compréhension partielle. Cependant, je ne pense pas pour l'instant avoir une compréhension suffisante pour répondre à cette dernière question –

Questions connexes