3 votes

Ce code est-il Thread-safe ?

Ceci est une version simplifiée de quelques lignes de code que je suis actuellement en train de maintenir :

int SomeFunc() 
{
  const long lIndex = m_lCurrentIndex;
  int nSum = 0;
  nSum += m_someArray[lIndex];
  nSum += m_someArray[lIndex];
  return nSum;
}

lCurrentIndex est mis à jour périodiquement par un autre thread. La question est : est-ce que faire une copie locale de m_CurrentIndex garantit que les deux accès à m_someArray utilisent le même index ?

Veuillez noter qu'il s'agit d'un exemple simplifié ; je réfléchis au concept de faire une copie locale, et non au code exact montré ici. Je sais que le compilateur mettra la valeur dans un registre, mais c'est quand même une copie locale par opposition à lire de l'Index courant deux fois.

Merci !

Édition : L'assignation initiale est sûre, les deux sont garantis d'être sur 32 bits dans notre configuration. Édition2 : Et ils sont correctement alignés sur une frontière de 32 bits (j'avais oublié celui-là)

15voto

Non, l'initialisation de la variable locale, qui lit une variable partagée, n'est pas nécessairement atomique. (considérez quel code serait nécessaire sur une plateforme 8 bits, par exemple) En général, la seule façon d'écrire un code thread-safe est d'utiliser des opérations atomiques spécifiées par votre compilateur et/ou système d'exploitation, ou d'utiliser des fonctionnalités de verrouillage du système d'exploitation.

6voto

Daniel Daranas Points 15123

faire une copie locale de m_CurrentIndex garantira-t-il que les deux accès à m_someArray utilisent le même index ?

Dans la même exécution de SomeFunc, oui, bien sûr. Une variable entière locale (lIndex) ne changera pas magiquement sa valeur au milieu de la fonction.

De toute évidence, les points suivants sont également vrais : la valeur réelle de m_someArray[lIndex] (par opposition à celle de lIndex) pourrait changer ; m_someArray en lui-même pourrait changer ; et ce que Neil a dit à propos de la validité de la valeur initiale de lIndex.

3voto

1800 INFORMATION Points 55907

Oui, la copie de l'index actuel veillera à ce que les deux accès au tableau utilisent le même index. Ce n'est pas vraiment ce à quoi je penserais comme étant "thread safe" cependant. Vous devez vous préoccuper de l'accès concurrentiel aux variables partagées. Pour moi, cela ressemble également à un domaine de préoccupation potentiel pour l'accès au tableau.

3voto

Greg Hewgill Points 356191

Cela devrait être thread-safe (du moins ça l'est sur tous les compilateurs/systèmes d'exploitation avec lesquels j'ai travaillé). Cependant, pour être encore plus sûr, vous pourriez déclarer m_lCurrentIndex comme volatile. Ainsi, le compilateur saura qu'il pourrait changer à tout moment.

1voto

Bombe Points 34185

Une autre question à poser ici est : est l'opération de copie de m_lCurrentIndex à lIndex une opération atomique? Si ce n'est pas le cas, vous pourriez finir par utiliser des valeurs très étranges qui ne feront probablement rien de bon. :)

Le point est : lorsque vous utilisez plusieurs threads, il n'y aura pas moyen d'échapper à un certain type de verrouillage ou de synchronisation.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X