¿Un GCD dispatch_async espera en NSLog ()?

Por lo que he leído sobre Grand Central Dispatch, GCD no hace multitarea preventiva; es todo un bucle de evento único. Tengo problemas para entender este resultado. Tengo dos queues haciendo algo de salida (al principio estaba leyendo / escribiendo algún estado compartido, pero pude simplificar esto y seguir obteniendo el mismo resultado).

dispatch_queue_t authQueue = dispatch_queue_create("authQueue", DISPATCH_QUEUE_SERIAL); dispatch_queue_t authQueue2 = dispatch_queue_create("authQueue", DISPATCH_QUEUE_SERIAL); dispatch_async(authQueue, ^{ NSLog(@"First Block"); NSLog(@"First Block Incrementing"); NSLog(@"First Block Incremented"); }); dispatch_async(authQueue, ^{ NSLog(@"Second Block"); NSLog(@"Second Block Incrementing"); NSLog(@"Second Block Incremented"); }); dispatch_async(authQueue2,^{ NSLog(@"Third Block"); NSLog(@"Third Block Incrementing"); NSLog(@"Third Block Incremented"); }); 

Obtengo el siguiente resultado:

 2011-12-15 13:47:17.746 App[80376:5d03] Third Block 2011-12-15 13:47:17.746 App[80376:1503] First Block 2011-12-15 13:47:17.746 App[80376:5d03] Third Block Incrementing 2011-12-15 13:47:17.746 App[80376:1503] First Block Incrementing 2011-12-15 13:47:17.748 App[80376:1503] First Block Incremented 2011-12-15 13:47:17.748 App[80376:5d03] Third Block Incremented 2011-12-15 13:47:17.750 App[80376:1503] Second Block 2011-12-15 13:47:17.750 App[80376:1503] Second Block Incrementing 2011-12-15 13:47:17.751 App[80376:1503] Second Block Incremented 

Como es evidente, los bloques no se ejecutan atómicamente. Mi única teoría es que GCD escribiendo a stdio a través de NSLog hace que la ejecución actual espere. No puedo encontrar nada relacionado con esto en la documentation de Apple. ¿Alguien puede explicar esto?

GCD no utiliza ningún tipo de "ciclo de events". Es una nueva característica del kernel en versiones recientes de Mac OS X e iOS, que en realidad no tienen ninguna otra tecnología similar que conozco.

El objective es terminar de ejecutar todo el código que le proporcione tan rápido como lo permita el hardware. Tenga en count que está apuntando a la hora de finalización más rápida, no a la hora de inicio más rápida. Una diferencia sutil, pero importante con un impacto real en el mundo sobre cómo funciona.

Si solo tiene un núcleo de CPU inactivo, teóricamente solo uno de ellos se ejecutará a la vez. Porque multitarea dentro de un solo núcleo es más lento que ejecutar dos tareas secuencialmente. Pero en realidad, este no es el caso. Si un núcleo de la CPU se queda inactivo o no está muy ocupado por un momento (por ejemplo, leer el disco duro o esperar a que otro progtwig responda (Xcode dibujando la salida NSLog)), entonces muy probablemente pasará a ejecutarse un segundo Elemento GCD, porque el que está haciendo actualmente está atascado.

Y, por supuesto, la mayoría de las veces tendrá más de un núcleo de CPU inactivo.

Tampoco necesariamente ejecutará las cosas en el order exacto en que las proporcione. GCD / el kernel tiene control sobre estos detalles.

Para su ejemplo específico, el depurador de Xcode probablemente solo sea capaz de procesar un único evento NSLog() a la vez (al less, tiene que hacer el dibujo de pantalla de uno en uno). Tienes dos queues y pueden comenzar a ejecutarse simultáneamente. Si envía dos NSLog() a la vez, una de ellas esperará que la otra termine primero. Debido a que no está haciendo otra cosa que imprimir cosas a Xcode, esas dos queues de GCD estarán en una carrera para ser las primeras en enviar datos de logging a Xcode. El primero tiene una ligera ventaja, pero es extremadamente ligero y, a menudo, no es suficiente para que abra una connection con Xcode primero.

Todo depende de qué resources de hardware estén disponibles en el hardware en ese nanosegundo específico en el time. No puede pnetworkingecirlo, y necesita estructurar sus queues apropiadamente para asumir algún control.

¿Dónde leyó que GCD no hace multitarea preventiva? Creo que estás equivocado. Está construido sobre el soporte de hilos provisto por el sistema y, por lo tanto, los bloques de GCD enviados a las queues pueden interrumpirse preventivamente.

El comportamiento que estás viendo es exactamente lo que espero. Los bloques primero y segundo se envían a la misma queue para que GCD se asegure de que el primer bloque se complete antes de que comience el segundo bloque. Sin embargo, el bloque tres se distribuye a una queue completamente diferente (es decir, se ejecutará en un hilo de background separado) y, por lo tanto, su salida se intercala con los otros dos bloques a medida que el sistema progtwig los hilos.

Lo que haya leído es incorrecto, a less que use una queue de despacho en serie, todos los bloques se ejecutarán simultáneamente.

Tus queues funcionan en 2 hilos concurrentes de background. Suministran concordantemente los posts NSLog. Mientras que un hilo hace salida NSlog, otro espera.
¿Qué sucede?