2010-02-14 7 views
7

¿Qué sucede cuando dos hilos establecen un BOOL en YES "al mismo tiempo"?¿BOOL es de lectura/escritura atómica en el Objetivo C?

+16

se abre un agujero de gusano a otra dimensión. – dreamlax

+5

Si los dos están poniéndolo a 'YES', no puede haber un problema si la escritura es atómica o no, ¿puede? –

+0

@CarlNorum que podría ser cierto, pero no es obvio para mí por qué –

Respuesta

6

No. Sin una construcción de bloqueo, leer/escribir cualquier variable tipo no es atómica en Objective C.

Si dos hilos Escritura SI al mismo tiempo a un BOOL, el resultado es SI, independientemente de cuál se en primer.

favor ver: Synchronizing Thread Execution

+2

Gracias, Mitch. Si uno ead lo establece en SÍ mientras que otro lo establece en NO, ¿puede haber corrupción de memoria? – Jacko

+1

http://developer.apple.com/mac/library/DOCUMENTATION/Cocoa/Conceptual/Multithreading/ThreadSafety/ThreadSafety.html ofrece una discusión muy detallada. Creo que usaré un int en lugar de un BOOL, y usaré las operaciones OSAtomic en este int. – Jacko

+0

La implicación de su pregunta es si puede que se rompa algún otro trozo de memoria. No; eso no puede suceder Lo peor que sucederá es que leerá un NO aparentemente después de que escribió un SÍ en otro hilo. – bbum

7

Aquí es código para solución sugerida por Jacko.
Uso volatileuint32_t con OSAtomicOr32Barrier y 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! Pero ¿por qué no usar 'OSAtomicOr32Barrier (allowed, & _IsRunning);' en lugar de condicional? –

+0

Sí, puede usar. –

+0

Ah, no es tan simple, lo siento. No puede usar la versión "o" para restablecer el indicador, es decir, debe usar la versión "y" para hacer esto (OSAtomicAnd32Barrier). –

3

tendría que divergen de la respuesta aceptada. Lo siento. Si bien el objetivo c no garantiza que las propiedades BOOL declaradas como no atómicas sean atómicas, tendría que adivinar que el hardware que más importa es el de (todos los dispositivos iOS y macos) tienen instrucciones para realizar lecturas de bytes y almacenar atómicamente. Entonces, a menos que Apple salga con Road Light OS ejecutando en un microcontrolador IBM que tenga un bus ancho de 5 bits para enviar bytes de 10 bits en , podría usar BOOLs no atómicos en una situación que requiera BOOLs atómicos. El código no sería portátil para Road Light OS, pero si puede sacrificar la futura protección de su código no atómico está bien para este caso de uso. Estoy seguro de que hay individuos endurecidos a la vez eso plantearía el desafío de desensamblar el eliminador BOOL sintetizado y el colocador para casos atómicos/no atómicos para ver cuál es la diferencia. Al menos en ARM.

Su comida para llevar de esto es probable que este

  1. puede declarar propiedades BOOL como atómica y que no le costará un centavo sobre todo IOS HW y MacOS apoya intrínsecamente.
  2. barreras de memoria son ortogonales a la atomicidad
  3. que definitivamente no debe usar 4 bytes para almacenar propiedades booleanos en a menos que esté en la lógica [muy] difusa. Es estúpido y derrochador, no desea ser un clon de un programador de Java, que no puede distinguir un carro de un doble, ¿o sí?
  4. las variables BOOL (que no obviamente apoyan decoradores atómicas/no atómica no sería atómica en algunas arquitecturas de bus estrechas C objetivo sería no puede utilizar de todos modos (microcontroladores con o sin alguna OS [muy] micro son C territorio & ensamblaje supongo. que por lo general no necesitan el equipaje tiempo de ejecución objc traería)