ios - gcd - nsoperationqueue swift 3 example
¿Diferencia entre dispatch_async y dispatch_sync en cola serie? (2)
Creé una cola en serie como esta:
dispatch_queue_t _serialQueue = dispatch_queue_create("com.example.name", DISPATCH_QUEUE_SERIAL);
¿Cuál es la diferencia entre dispatch_async
llamado así?
dispatch_async(_serialQueue, ^{ /* TASK 1 */ });
dispatch_async(_serialQueue, ^{ /* TASK 2 */ });
Y dispatch_sync
llamado así en esta cola en serie?
dispatch_sync(_serialQueue, ^{ /* TASK 1 */ });
dispatch_sync(_serialQueue, ^{ /* TASK 2 */ });
Según tengo entendido, independientemente de qué método de envío se utilice, TASK 1
se ejecutará y completará antes de TASK 2
, ¿correcto?
La diferencia entre dispatch_sync
y dispatch_async
es simple.
En ambos ejemplos, TASK 1
siempre se ejecutará antes de TASK 2
porque se envió antes.
En el ejemplo dispatch_sync
, sin embargo, no enviará TASK 2
hasta después TASK 1
se haya enviado y ejecutado TASK 1
. Esto se llama "blocking" . Su código espera (o "bloquea") hasta que se ejecuta la tarea.
En el ejemplo de dispatch_async
, su código no esperará a que se complete la ejecución. Ambos bloques se enviarán (y se pondrán en cola) a la cola y el resto del código continuará ejecutándose en ese hilo. Luego, en algún momento en el futuro (dependiendo de qué más haya sido enviado a su cola), se ejecutará la Task 1
y luego se ejecutará la Task 2
.
Sí. El uso de la cola en serie garantiza la ejecución en serie de las tareas. La única diferencia es que dispatch_sync
solo regresa después de que el bloque finaliza, mientras que dispatch_async
regresa después de que se agrega a la cola y puede que no termine.
para este código
dispatch_async(_serialQueue, ^{ printf("1"); });
printf("2");
dispatch_async(_serialQueue, ^{ printf("3"); });
printf("4");
Puede imprimir 2413
o 2143
o 1234
pero 1
siempre antes de 3
para este código
dispatch_sync(_serialQueue, ^{ printf("1"); });
printf("2");
dispatch_sync(_serialQueue, ^{ printf("3"); });
printf("4");
siempre imprime 1234
Nota: para el primer código, no se imprimirá 1324
. Porque printf("3")
se envía después de que se ejecuta printf("2")
. Y una tarea solo puede ejecutarse después de su envío.
El tiempo de ejecución de las tareas no cambia nada. Este código siempre imprime 12
dispatch_async(_serialQueue, ^{ sleep(1000);printf("1"); });
dispatch_async(_serialQueue, ^{ printf("2"); });
Lo que puede suceder es
- Subproceso 1: dispatch_async una tarea que consume tiempo (tarea 1) a la cola en serie
- Subproceso 2: comience a ejecutar la tarea 1
- Subproceso 1: dispatch_async otra tarea (tarea 2) en cola serie
- Subproceso 2: finalizó la tarea 1. comience a ejecutar la tarea 2
- Subproceso 2: finalizó la tarea 2.
y siempre ves 12