tutorials tutorial example ios concurrency grand-central-dispatch

tutorial - secuencia de ejecución de cola simultánea personalizada de iOS GCD



nsoperationqueue swift 3 example (2)

"Concurrente" significa que se ejecutan al mismo tiempo y no se deben hacer suposiciones sobre dónde se encontrarán en un momento dado en ninguno de ellos y cuáles terminarán primero. Ese es todo el significado e implicancia de la concurrencia: entre una línea de código y la siguiente en una operación simultánea, incluso durante una línea de código, cualquier otra cosa de cualquier otra operación simultánea podría estar sucediendo.

Entonces, en respuesta a su pregunta en particular, estas tareas pueden haber comenzado en un orden conocido, pero eso sucedió muy rápidamente, y después de ese punto su progreso se intercala de forma impredecible. Y sus llamadas NSLog son parte de ese progreso; ¡ellos no dicen ni pueden decir cuándo comenzaron las tareas!

Tengo una pregunta sobre este tema, según los documentos de Apple

Las colas concurrentes concurrentes (también conocidas como un tipo de cola de despacho global) ejecutan una o más tareas al mismo tiempo, pero las tareas aún se inician en el orden en que se agregaron a la cola. Las tareas que se están ejecutando actualmente se ejecutan en distintos subprocesos administrados por la cola de distribución. El número exacto de tareas que se ejecutan en un punto determinado es variable y depende de las condiciones del sistema. En iOS 5 y posterior, puede crear colas de distribución simultáneas especificando DISPATCH_QUEUE_CONCURRENT como el tipo de cola. Además, hay cuatro colas simultáneas globales predefinidas para que use su aplicación. Para obtener más información sobre cómo obtener las colas simultáneas globales, consulte Obtención de colas de envío simultáneas globales.

Y hago una prueba, usando el código de muestra,

dispatch_queue_t concurrentQueue; concurrentQueue = dispatch_queue_create("com.gcd.concurrentQueue", DISPATCH_QUEUE_CONCURRENT); dispatch_async(concurrentQueue, ^{ NSLog(@"First job "); }); dispatch_async(concurrentQueue, ^{ NSLog(@"Second job"); }); dispatch_async(concurrentQueue, ^{ NSLog(@"Third job "); });

Pero los resultados no parecen ser el orden en que se agregan, aquí están los resultados,

2015-06-03 18:36:38.114 GooglyPuff[58461:1110680] First job 2015-06-03 18:36:38.114 GooglyPuff[58461:1110682] Third job 2015-06-03 18:36:38.114 GooglyPuff[58461:1110679] Second job

Entonces mi pregunta es, ¿no debería ser Primero, Segundo, Tercero?

Cualquier consejo es bienvenido, y gracias por su ayuda.


La documentación es correcta: comenzarán en el orden en que los agregó a la cola. Una vez en la cola, se iniciarán uno después de otro, pero en hilos concurrentes. El orden que terminarán dependerá de cuánto tiempo llevará ejecutar la tarea. Aquí hay un experimento mental, imagine que su código era así:

dispatch_async(concurrentQueue, ^{ JobThatTakes_3_SecToExecute(); // Job 1 (3 seconds to execute) }); dispatch_async(concurrentQueue, ^{ JobThatTakes_2_SecToExecute(); // Job 2 (2 seconds to execute) }); dispatch_async(concurrentQueue, ^{ JobThatTakes_1_SecToExecute(); // Job 3 (1 second to execute) });

La sobrecarga dentro y fuera de la cola debe ser muy pequeña en comparación con estas longitudes de trabajo, por lo que esperaría que terminen en aproximadamente el tiempo que tarda su tarea en ejecutarse. En este caso, terminarían aproximadamente 1 segundo de diferencia comenzando con Job 3, luego 2, luego 1. El tiempo total que la cola tardaría en completarse será aproximadamente la duración de Job 1, ya que tarda más en ejecutarse. Esto es encantador, ya que el tiempo total lo establece principalmente el trabajo más largo, no la suma de los trabajos. Sin embargo, no tiene voz en el orden en que terminan, ya que eso está dictado por la duración de la tarea.

Cambie dispatch_async a dispatch_sync en este ejemplo y la cola tardará aproximadamente 6 segundos en completarse. Aparecerán en este orden: Trabajo 1, 2, luego 3. Esto garantizará que sus resultados salgan en el orden que usted quería, pero tomará mucho más tiempo.

Así que de vuelta a la importancia de lo que los documentos significan por "las tareas todavía se inician en el orden en que se agregaron a la cola" para las colas concurrentes. Esto será notable si su trabajo tiene recursos limitados. Supongamos que está realizando una gran cantidad de tareas de larga duración en una cola simultánea en una máquina con 2 CPU. Es poco probable que pueda ejecutar una docena de tareas de vinculación de CPU al mismo tiempo aquí; algunos tendrán que esperar mientras otros corren. El orden en que los pones en la cola decidirá quién se ejecutará a continuación a medida que los recursos se liberen. En su ejemplo, las tareas son de muy corta duración e implican el bloqueo de la consola (como mencionó Rob), por lo que la carga en cola / bloqueo puede interferir con sus expectativas.

Otro motivo (probablemente más importante) que importa el orden de ejecución en colas concurrentes es cuando se usan barreras. Es posible que deba ejecutar algún tipo de tarea cada N otras tareas, que es donde una barrera sería útil. El orden de ejecución fijo garantizará que la barrera se ejecute después de que se hayan completado al mismo tiempo N tareas, siempre que ponga la barrera en la cola en el lugar correcto.