2010-12-16 9 views
5

soy bastante nuevo en la programación multi-hilo y pregunto si está bien o para hacer una propiedad comolo hace tiene sentido hacer atómica una bandera BOOL en múltiples hilos de programación

@property BOOL shouldDoIt; //atomic 

que será utilizado en un bucle que se llama en el fondo

- (void) loop{ 
    // ... do stuff ... 
    if (self.shouldDoIt) { 
     [self doIt]; 
     self.shouldDoIt = NO; 
    } 
    // ... do more stuff ... 
} 

y cambiado en un método llamado desde el hilo principal

- (void) methodCalledFromMainThread{ 
    self.shouldDoIt = YES; 
} 

¿Tengo tengo para hacerlo atómico o no cambia nada? Sé que atómico es lento en comparación con no atómico y mi programa necesita más velocidad, pero si no se usa atómico, ¿podría fallar hacer if (shouldDoIt){?

Respuesta

2

La respuesta es totalmente dependiente de la respuesta a la pregunta: "¿Qué se necesita para ejecutar doIt exactamente una vez por cada vez que el hilo principal establece el indicador shouldDoIt"

Si la respuesta a esa pregunta es "sí", entonces su código no funcionará porque el hilo principal podría establecer shouldDoIt a YES después de haber iniciado doIt pero antes de haber restablecido la bandera.

Si la respuesta es "no", en este caso, lo que tiene es bueno, excepto que en una configuración de múltiples CPU, la bandera puede almacenarse en caché de tal manera que el otro hilo no ver el cambio Por lo tanto, probablemente al menos desee utilizar OSAtomicTestAndClearBarrier() y OSAtomicTestAndSetBarrier(), que son de bajo nivel, por lo tanto, tan rápido como pueda.

Sin embargo, soy escéptico de que tenga que hacer esto. Creo que es posible que encuentre que refactorizar el diseño de alguna manera obtendrá mejores resultados dependiendo de lo que esté tratando de hacer en doIt, do stuff y do more stuff.

+0

Si solo usamos un subproceso ** writer ** thread y ** reader **, no necesitamos acceso entrelazado a la variable ** shouldDoI ** por supuesto, el subproceso principal primero debe esperar ** shouldDoI ** para convertirse en 0 antes de volver a establecer el ** shouldDoI **. –

+0

JeremyP me has hecho darme cuenta de la diferencia entre volver a configurar NODoIt a NO antes y después de doIt. +1 para OSAtomicTestAndClear/SetBarrier();) – nacho4d

0

Lea primero el Threading Programming Guide de Apple y creo que necesita un NSLock , pero tenga cuidado de que pueda encontrar un punto muerto. buena suerte

+0

Entiendo que NSLock es una alternativa, pero creo que es demasiado trabajo y estoy tratando de determinar si 'atómico' es suficiente cuando hay una sola bandera BOOL como este caso. – nacho4d

+0

Si configura una propiedad atómica, tendrá bloqueos de mutex en setter y getter. En tu caso, si configuras el bool en yes y el ir a un thread posterior y haces algunas cosas, y luego de que hagas las cosas, lo establecerás en no. No veo ningún problema aquí. –

2

En puede enhebrar tiene una BOOL que desea establecer o ningún después de hacer algún trabajo en el hilo de vuelta a

[NSThread detachNewThreadSelector:@selector(backThreadAction:) toTarget:self withObject:nil]; 


-(void) backThreadAction:(id*)someObject{ 
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 

    //do stuff here 

    [self performSelectorOnMainThread:@selector(didFinishBackThreadAction:) withObject:nil waitUntilDone:NO]; 
    [pool release]; 
} 

-(void) didFinishBackThreadAction:(id *)someObject{ 
    //set your bool to no 
} 
+0

+1 para el código;) Supongo que puedo hacer lo mismo con GCD (ya que no estoy usando NSThread o performSelectorOn ...API) – nacho4d

0

en esta parte del código:

if (self.shouldDoIt) { 
    [self doIt]; 

shouldDoTt es atómico no garantiza que todavía sea true cuando llame a doIt. Debe usar un candado para asegurarse de que el valor no haya cambiado después de la prueba y antes de que realmente haga lo que tiene que hacer.

+0

¡No es cierto, si solo usamos un hilo de escritor y un hilo de lector! –

Cuestiones relacionadas