2010-02-14 4 views
7

Que se passe-t-il lorsque deux threads définissent un BOOL sur YES "en même temps"?Est-ce que BOOL est en lecture/écriture atomique en Objective C?

+16

il ouvre un trou de ver à une autre dimension. – dreamlax

+5

Si elles sont à la fois la mise à 'YES', il ne peut y avoir un problème si l'écriture est atomique ou non, peut-il? –

+0

@CarlNorum qui pourrait être vrai, mais ce n'est pas évident pour moi pourquoi –

Répondre

6

Non Sans une construction de verrouillage, la lecture/écriture toute variable de type n'est pas atomique Objective C.

Si deux threads écrivent OUI en même temps à un BOOL, le résultat est OUI, peu importe que l'on obtient en premier.

S'il vous plaît voir: Synchronizing Thread Execution

+2

Merci, Mitch. ead le définit sur YES alors qu'un autre le définit sur NO, peut-il y avoir une corruption de mémoire? – Jacko

+1

http://developer.apple.com/mac/library/DOCUMENTATION/Cocoa/Conceptual/Multithreading/ThreadSafety/ThreadSafety.html donne une discussion très approfondie. Je pense que je vais utiliser un int au lieu d'un BOOL, et utiliser les opérations OSAtomic sur cet int. – Jacko

+0

L'implication de votre question est de savoir si un autre morceau de mémoire peut être croqué ou non. Non; cela ne peut pas arriver. Le pire, c'est que vous lirez un NON après avoir écrit un OUI dans un autre fil. – bbum

7

Voici le code pour la solution proposée par Jacko.
Utilisez volatileuint32_t avec OSAtomicOr32Barrier et OSAtomicAnd32Barrier

#import <libkern/OSAtomic.h> 

volatile uint32_t _IsRunning; 

- (BOOL)isRunning { 
    return _IsRunning != 0; 
} 

- (void)setIsRunning:(BOOL)allowed { 

    if (allowed) { 
     OSAtomicOr32Barrier(1, & _IsRunning); //Atomic bitwise OR of two 32-bit values with barrier 
    } else { 
     OSAtomicAnd32Barrier(0, & _IsRunning); //Atomic bitwise AND of two 32-bit values with barrier. 
    } 
} 
+0

Cool! Mais pourquoi ne pas simplement utiliser OSAtomicOr32Barrier (autorisé, & _IsRunning); 'à la place de l'instruction conditionnelle? –

+0

Oui, vous pouvez utiliser. –

+0

Ah, ce n'est pas si simple, désolé. Vous ne pouvez pas utiliser la version "ou" pour réinitialiser le drapeau, c'est-à-dire que vous devez utiliser la version "et" pour le faire (OSAtomicAnd32Barrier). –

3

Je dois diverger de la réponse acceptée. Pardon. Bien que l'objectif c ne garantisse pas que les propriétés BOOL déclarées comme non atomiques sont en fait atomiques, je devrais deviner que le matériel dont vous vous souciez le plus (tous les périphériques iOS et MacOS) a des instructions pour effectuer des lectures d'octets et des sauvegardes atomiques. Donc, à moins qu'Apple sorte avec Road Light OS exécutant sur un microcontrôleur IBM qui a un bus de 5 bits pour envoyer 10 octets sur , vous pouvez tout aussi bien utiliser des BOOL non atomiques dans une situation qui appelle des BOOL atomiques. Le code ne serait pas portable à Road Light OS, mais si vous pouvez sacrifier l'avenir de votre code non atomique, c'est bien pour ce cas d'utilisation. Je suis sûr qu'il y a des individus endurcis sur le s.o. cela soulèverait le défi de désassembler le getter BOOL synthétisé et le setter pour les cas atomiques/non atomiques pour voir quelle est la différence. Au moins sur ARM.

Votre repas à emporter il est probable que ce

  1. vous pouvez déclarer des propriétés booléennes comme atomique et il ne vous coûtera pas un sou sur tous les iOS et Mac OS HW soutient intrinsèquement.
  2. barrières de mémoire sont orthogonales à atomicité
  3. vous certainement ne devriez pas utiliser 4 propriétés d'octets pour stocker booléens dans , sauf si vous êtes dans la logique floue [très]. C'est idiot et gaspilleur, vous ne voulez pas être un clone d'un programmeur Java, qui ne peut pas dire un flotteur d'un double, ou vous?
  4. variables BOOL (qui ne supportent pas de toute évidence atomique/décorateurs nonatomic ne serait pas atomique sur certaines architectures de bus étroites objectif C ne pas être utilisé sur de toute façon (microcontrôleurs avec ou sans certains micro OS [très] sont le territoire d'assemblage C & Je suppose. ils ne nécessite généralement pas le temps d'exécution objc bagages apporterait)