2011-10-25 7 views
7

Procedente de Java, estoy intentando aprender seguridad de subprocesos en Objective-C. Hasta ahora he incliné queUsando @synchronized, volátil y OSMemoryBarrier() todos juntos. ¿Implica uno el otro?

  • bloques @synchronized impiden el acceso concurrente a la misma bloque de código
  • las variables volátiles aseguran la visibilidad de los cambios cruzando hilos
  • OSMemoryBarrier(); asegura el correcto orden de acceso

Mi pregunta es: ¿alguno de ellos implica uno o más de los otros? Si quiero los tres, ¿necesito usar las tres técnicas?

Ejemplo:

volatile int first = 0; 
volatile int second = 0; 

[...] 

@synchronized { 
    OSMemoryBarrier(); 
    first++; 
    OSMemoryBarrier(); 
    second++; 
    OSMemoryBarrier(); 
} 

En Java los tres están asegurados al entrar y salir de un bloque sincronizada y al leer o escribir una variable volátil. ¿Cierto?

Respuesta

1

La directiva @synchronized se convierte de la siguiente manera ...

- (NSString *)myString { 
    @synchronized(self) { 
    return [[myString retain] autorelease]; 
    } 
} 

se convierte ...

- (NSString *)myString { 
    NSString *retval = nil; 
    pthread_mutex_t *self_mutex = LOOK_UP_MUTEX(self); 
    pthread_mutex_lock(self_mutex); 
    retval = [[myString retain] autorelease]; 
    pthread_mutex_unlock(self_mutex); 
    return retval; 
} 
+0

Entonces, ¿entrar y salir del bloque sincronizado constituye el paso de barreras de memoria? Y si el acceso a una variable está protegido por un bloque sincronizado, la variable no necesita ser volátil, porque los cambios son siempre visibles para otros hilos. – Twilite

+0

Encontré más en volátil en las respuestas a esta pregunta: http://stackoverflow.com/questions/6866206/volatile-and-createthread Parece que volátil no representa una barrera de memoria y es inútil para la sincronización del acceso entre subprocesos. – Twilite

0

@synchronized no protege a un bloque de código de ser volvió a entrar - que impide la ejecución cualquier código que también usa @synchronized con el mismo objeto. Así que si usted tiene dos métodos

- (void)method1 { 
    @synchronized (self) { dothis(); } 
} 
- (void)method2 { 
    @synchronized (self) { dothat(); } 
} 

y dos hilos de diferentes llamar metodo1 y metodo2 para el mismo objeto, a continuación, DoThis() y dothat() serán llamados uno tras otro. Por supuesto, eso también es cierto si dos hilos diferentes llaman a method1 para el mismo objeto. @synchronized no impide que ingrese un bloque en el mismo subproceso, por lo que en el ejemplo anterior dothis() podría llamar a [self method2] y no se bloquearía.

Si está utilizando volátil u OSMemoryBarrier(), le sugiero que su diseño es mucho, mucho, demasiado complicado y que tarde o temprano tendrá problemas.

Cuestiones relacionadas