10

Mi aplicación hace un uso intensivo de GCD, y casi todo se divide en tareas pequeñas manejadas por despachos. Sin embargo, el modelo de datos subyacente es principalmente leído y solo ocasionalmente escrito.Bloqueo de lectura y escritura con GCD

Actualmente utilizo bloqueos para evitar cambios en las estructuras de datos críticas durante la lectura. Pero después de buscar más bloqueos hoy, encontré NSConditionLock y alguna página sobre bloqueos de lectura y escritura. Esto último es exactamente lo que necesito.

Encontré esta implementación: http://cocoaheads.byu.edu/wiki/locks. Mi pregunta es, ¿funcionará esta implementación con GCD, ya que usa PThreads?

Respuesta

20

Funcionará. pthreads es la API de subprocesamiento que subyace a todas las otras API que usan subprocesos en Mac OS X. (Debajo de eso hay activaciones de subprocesos Mach, pero eso es SPI, no API.) De todos modos, los bloqueos pthreads realmente no requieren que uses pthreads trapos.

Sin embargo,, GCD ofrece una mejor alternativa que iOS 5: dispatch_barrier_async(). Básicamente, tienes una cola concurrente privada. Usted le envía todas las operaciones de lectura de la manera normal. Usted le envía operaciones de escritura usando las rutinas de barrera. Ta-da! Bloqueo de lectura y escritura

Puede obtener más información al respecto si tiene acceso al WWDC 2011 session video for Session 210 - Mastering Grand Central Dispatch.

+1

Ah, había leído sobre las barreras, pero en ese momento no podía pensar en una aplicación práctica (Apenas usé multihilo en aquel entonces) y olvidé todo sobre ellas. Gracias, intentaré ver si puedo usar eso. –

+3

Mike Ash también proporciona un buen ejemplo de cómo lograr la sincronización lector-escritor usando GCD. http://www.mikeash.com/pyblog/friday-qa-2011-10-14-whats-new-in-gcd.html –

1

Es posible que también desee considerar mantener una cola en serie para todas las operaciones de lectura/escritura. A continuación, puede dispatch_sync() escribir en esa cola para asegurarse de que los cambios en el modelo de datos se apliquen con prontitud y dispatch_async() todas las lecturas para asegurarse de mantener un buen rendimiento en la aplicación.

Dado que tiene una única cola en serie en la que tienen lugar todas las lecturas y escrituras, se asegura de que no se produzcan lecturas durante una escritura. Esto es mucho menos costoso que un bloqueo, pero significa que no puede ejecutar múltiples operaciones de "lectura" simultáneamente. Es poco probable que cause un problema para la mayoría de las aplicaciones.

El uso de dispatch_barrier_async() puede significar que las escrituras que realice tardan un tiempo arbitrario en comprometerse porque todas las tareas preexistentes en la cola deben completarse antes de que se ejecute su bloque de barrera.

+0

Hmm, ni siquiera me di cuenta de que el envío asincrónico era posible en una cola en serie. Esto suena como una idea interesante ... Todas las lecturas son ediciones razonablemente pequeñas, aunque las escrituras usualmente significan leer, editar y luego guardar los datos nuevamente. –

+5

Por lo general, haces lo contrario de lo que se sugiere aquí. Por lo general, las lecturas deben enviarse sincrónicamente, ya que a menudo debe tener el resultado antes de regresar a la persona que llama. Las escrituras se pueden realizar de forma asincrónica, ya que a la persona que llama solo le preocupa que el estado observable desde el exterior sea coherente con la fecha que se escribió, que es porque no puede continuar la lectura hasta que la escritura se completa porque la cola es en serie. No ayuda con múltiples lectores, como se señaló. –

Cuestiones relacionadas