2012-10-07 23 views
13

Soy un experimentado programador de .NET y estiro mis piernas con iOS. Uno de mis constructos multi-threading favoritos en .NET es el ReaderWriterLock. Permite múltiples lectores o un solo escritor. La única característica que realmente me falta en iOS es que los bloqueos son reentrantes. Es decir, reader threads can acquire the read lock multiple times, siempre que lo liberen la misma cantidad de veces. Del mismo modo, el hilo de escritor único puede adquirir el bloqueo varias veces siempre que libere el bloqueo por un número equivalente.construcción de bloqueo de lectura/escritura reentrante?

He revisado el iOS Framework y ninguno de los constructos parece ofrecer el mismo soporte, incluida la reentrada. También miré en la biblioteca pthread. Encontré rwlock, pero no permite la reentrada.

¿Hay algo en iOS que permita el reentrada de los bloqueos de lectura y escritura?

Respuesta

2

Desde el IOS Threading Programming Guide:

El sistema es compatible con las cerraduras de lectura-escritura utilizando sólo los hilos POSIX. Para obtener más información sobre cómo utilizar estos bloqueos, consulte la página del manual pthread.

Así que supongo que si pthreads no admiten la reentrada, la respuesta es no.

16

Sí, la directiva @synchronized es reentrante. Consulte Using the @synchronized Directive en la Guía de programación de Threading y también Threading en el Lenguaje de programación de ObjC.

Dicho esto, casi nunca deberías usar esto en iOS. En la mayoría de los casos, puede evitar bloqueos de todo tipo, y mucho menos bloqueos de peso pesado (lento) como bloqueos de reentrada. Consulte la Guía de programación de simultaneidad, y particularmente la sección Migrating Away from Threads, para obtener información detallada acerca de los enfoques basados ​​en colas que iOS prefiere sobre la administración y el bloqueo de subprocesos manuales.

Por ejemplo, el bloqueo de lectura/escritura funciona así el uso de Grand Central Dispatch:

- (id)init { 
    ... 
    _someObjectQueue = dispatch_queue_create("com.myapp.someObject", 
              DISPATCH_QUEUE_CONCURRENT); 
} 

// In iOS 5 you need to release disptach_release(_someObjectQueue) in dealloc, 
// but not in iOS 6. 

- (id)someObject { 
    __block id result; 
    dispatch_sync(self.someObjectQueue, ^{ 
    result = _someObject; 
    }); 
    return result; 
} 

- (void)setSomeObject:(id)newValue { 
    dispatch_barrier_async(self.queue, ^{ 
    _someObject = newValue; 
}); 

Este enfoque permite a los lectores en paralelo sin limitación, con los escritores exclusivos, garantizando al mismo tiempo que los escritores nunca se muere de hambre y que escribe y lee son serializado, todo mientras se evitan las llamadas al núcleo a menos que exista una disputa real. Eso es todo para decir que es muy rápido y simple.

Cuando aparece un lector, pone en cola una solicitud para leer el valor y espera a que se procese. Cuando aparece un escritor, pone en cola una solicitud de barrera para actualizarlo, lo que requiere que no se estén ejecutando otras solicitudes de esa cola. Con esta construcción, el desarrollador no necesita administrar ningún bloqueo. Simplemente coloque las cosas en la cola en el orden que desee que se ejecuten.

+0

'@ synchronized' es reingresante pero no es compatible con varios lectores. GCD requeriría una reestructuración significativa de mi código existente. – Askable

+0

Tiene razón en que @synchronized no es compatible con varios lectores. Este enfoque es inusual en Cocoa, y no estoy familiarizado con una gran solución más allá de pthread_rwlock_init que recuerdo no es reentrante. Este tipo de bloqueo, como dije, es muy ineficiente, y el iOS y el Mac moderno tienen mecanismos más rápidos, seguros y simples en GCD y NSOperationQueue. En la Mac más antigua, se prefería la multitarea cooperativa (runloop). .NET hereda su amor por los hilos y bloqueos de Java. ObjC desalienta el enhebrado explícito. Cocoa no es como .NET y vale la pena aprender el enfoque Cocoa en iOS. –

+0

(Sí, sé que esto realmente no responde a su pregunta. Lo siento). –

Cuestiones relacionadas