Supposons que nous avons le code suivant:multithreading .NET, le modèle et la mémoire volatile
class Program
{
static volatile bool flag1;
static volatile bool flag2;
static volatile int val;
static void Main(string[] args)
{
for (int i = 0; i < 10000 * 10000; i++)
{
if (i % 500000 == 0)
{
Console.WriteLine("{0:#,0}",i);
}
flag1 = false;
flag2 = false;
val = 0;
Parallel.Invoke(A1, A2);
if (val == 0)
throw new Exception(string.Format("{0:#,0}: {1}, {2}", i, flag1, flag2));
}
}
static void A1()
{
flag2 = true;
if (flag1)
val = 1;
}
static void A2()
{
flag1 = true;
if (flag2)
val = 2;
}
}
}
C'est la faute! La principale question est pourquoi ... Je suppose que les opérations de réorganisation du processeur avec flag1 = true; et si l'instruction (flag2), mais les variables flag1 et flag2 marquées comme champs volatiles ...
Merci beaucoup! Mais dans l'article à propos de.modèle de mémoire net ("Comprendre l'impact des techniques à faible verrouillage dans les applications multithread" http://msdn.microsoft.com/en-us/magazine/cc163715.aspx) dans la section "Un modèle détendu: ECMA" nous pouvons voir , 1. Les lectures et écritures ne peuvent pas bouger avant une lecture volatile. 2. Les lectures et les écritures ne peuvent pas bouger après une écriture volatile. Est-ce que c'est faux? Je peux juste comprendre ... Peut être dans l'article signifie quelque chose d'autre? ... –
+1 pour mentionner le livre - actuellement en train de le lire moi-même (déjà à mi-chemin ;-) –
@ fedor-serdukov: Je me souviens peut-être - mais j'essaie d'être nettement plus sûr que nécessaire pour éviter un comportement inattendu (surtout après quelques changements de maintenance). De plus, je ne pense pas que votre code soit hors service pour que l'exception soit lancée. 'A1' et' A2' pourraient s'intercaler de sorte que les deux drapeaux soient positionnés avant que l'une ou l'autre condition soit vérifiée, en fait une fois que le pool de threads est lancé, je m'attendrais à ce que cela arrive de temps en temps sur un système multicœur. – Richard