http://gcc.gnu.org/onlineDocs/gcc-4.4.2/gcc/atomic-builtins.html
Je crois que le code suivant augmente la valeur de Var atomique.
volatile int var = 0;
__sync_fetch_and_add( &var, 1 )
J'ai compris les codes ci-dessus comme la logique suivante :
Cependant, je doute si ce qui suit est atomique, aussi
volatile int var = 0;
volatile int num = 1;
__sync_fetch_and_add( &var, num )
Comme il peut être interprété comme
Après le numéro 2 est exécuté, mais avant # 3, la CPU/thread est interrompue et une autre CPU/thread met à jour la valeur de Num variable.
En d'autres termes, lors de l'utilisation _ Sync * () de GCC, puis-je utiliser une variable, pas une constante, comme deuxième argument?
Cela ne casse-t-il pas l'atomicité?
L'opération est vraiment deux opérations.
__sync_fetch_and_add( &var, num )
Chargement num
est atomique. L'ajout à var
est atomique. Mais deux opérations atomiques ne font pas une opération atomique lorsqu'elles sont rassemblées. C'est pourquoi il est si difficile d'inventer de nouvelles structures de données sans verrouillage. En général, deux opérations de fil-sécurité ne font pas nécessairement une opération de fil-sécurité lorsqu'elles sont composées. C'est la raison pour laquelle il est si difficile de faire des applications multithreadées correctes.
Tu vois, __sync_fetch_and_add
est en effet atomique, mais cela se comporte comme une fonction ordinaire - il faut donc la valeur actuelle de "NUM" comme paramètre. Il n'est pas tout à fait correct de dire que l'atomicité de la fonction est cassée - car il incombe à l'appelant de charger la valeur de num
, et ce n'est pas une partie de l'interface de la fonction. Je pouvais également me plaindre de cela:
__sync_fetch_and_add(&var, some_really_long_function());
Ou pire,
__sync_fetch_and_add(long_function_1(), long_function_2());
Vous dites qu'il "peut être interprété comme"
Mais selon la spécification C, ce n'est pas le cas mai être interprété de cette façon, mais plutôt, il doit être interprété de cette façon, sinon le compilateur ne serait pas conforme (en fait , il pourrait échanger n ° 1 et n ° 2, mais ce n'est pas important ici).