Multicœur et synchronisation

Le code ci-dessus double la variable partagée counter au moyen de CAS(&p, valeur attendue, nouvelle valeur). Dans quel cas le CAS échoue-t-il et la boucle recommence-t-elle ?

int old, new;
do {
    old = counter;
    new = old * 2;
} while (!CAS(&counter, old, new));
  1. ALorsque counter vaut 0
  2. BLorsqu’un autre thread a modifié counter entre la lecture de old et l’exécution du CAS
  3. CLorsque new est supérieur à old
Afficher la réponse et l'explication

Réponse : B. Lorsqu’un autre thread a modifié counter entre la lecture de old et l’exécution du CAS

CAS écrit la nouvelle valeur si counter vaut toujours old, la valeur lue. Si un autre thread a modifié la valeur entre-temps, la valeur new locale a été calculée à partir d’une valeur obsolète : CAS n’écrit pas et renvoie un échec. La boucle relit la valeur la plus récente et refait le calcul. Pour une simple addition, fetch-and-add suffit, mais cette forme permet d’effectuer de façon indivisible toute mise à jour arbitraire, comme un doublement.

S'entraîner sur ce thème Retour au thème

Autres questions sur Multicœur et synchronisation

  1. Avec une paire d’instructions comme LR/SC (load-reserved/store-conditional) de RISC-V, dans quel cas le SC (store-conditional) échoue-t-il ?
  2. Quelle description du problème ABA, qui affecte les structures de données sans verrou utilisant CAS, est correcte ?
  3. Quel est le fonctionnement d’une instruction fetch-and-add, comme amoadd.w de RISC-V ou lock xadd de x86 ?
  4. Quelle description du verrou à attente active (spinlock) est correcte ?
  5. Dans quelle situation le spinlock est-il le moins adapté ?

Comparatifs sur ce thème