2011-07-29 8 views
27

el siguiente código:comportamiento dispatch_get_global_queue

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{ 
    for (int i=0; i<100000; i++) { 
     NSLog(@"HIGH 1 %d", i); 
    } 
}); 
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{ 
    for (int i=0; i<100000; i++) { 
     NSLog(@"LOW %d", i); 
    } 
}); 
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{ 
    for (int i=0; i<100000; i++) { 
     NSLog(@"HIGH 2 %d", i); 
    } 
}); 

resultados en mezcla de 2 y bajos registros de alta 1, alta.

Cómo es que imprime registros high1 y high2 simultáneamente. ¿no están ambos blogs high1 y high2 en la misma cola? Entonces, ¿no debería terminar high1 block antes de comenzar a ejecutar high2 block?

Respuesta

22

Eso depende de la máquina en la que se esté ejecutando. Sospecho que está ejecutando esto en su Mac, porque GCD creará automáticamente suficientes hilos para el sistema específico para trabajos en las colas globales. Por lo tanto, es probable que tenga más de un núcleo, por lo que GCD ejecuta sus trabajos en ambos núcleos.

Si crea su cola usando dispatch_queue_create, obtiene una cola en serie, y se le garantiza un comportamiento FIFO.

FWIW (aunque no deberías confiar en este comportamiento), si ejecutas eso en el iPhone, sospecho que verás el comportamiento de cola en serie, porque tu iPhone es de un solo núcleo. Sin embargo, no confíe en esto, ¡el iPad 2 es multinúcleo, creo!

EDIT:

Documentación para dispatch_get_global_queue: Devuelve una conocida mundial concurrente cola de un nivel de prioridad dado.

6

Acaba de ilustrar por qué no debe llamar a métodos que no son seguros para subprocesos dentro de dispatch_async. Si hay suficientes núcleos de procesamiento para ejecutar más trabajos, GCD continuará y acumulará trabajo en ellos, independientemente de si los trabajos anteriores en una cola determinada ya han regresado. El mismo comportamiento se puede lograr en OS X 10.7 creando sus propias colas con:

dispatch_queue_create(NULL, DISPATCH_QUEUE_CONCURRENT); 

Obviamente NSLog() se puede llamar tantas veces como desee sin tener que preocuparse acerca de cómo obtener los errores de acceso malas o similar, pero si le preocupa seguridad de subprocesos o el orden en que vuelven sus trabajos considere utilizar grupos de despacho.

0

dispatch_get_global_queue es una especie de cola de simultaneidad. Como especifica la misma prioridad para high1 y high2, el resultado es una mezcla de high1 y high2. Después de eso, será el resultado bajo ya que tiene una prioridad más baja.