¿Por qué la concurrencia?
Tan pronto como agrega tareas pesadas a su aplicación, como la carga de datos, ralentiza el trabajo de la interfaz de usuario o incluso lo congela. La concurrencia le permite realizar 2 o más tareas “simultáneamente”. La desventaja de este enfoque es que la seguridad de los hilos no siempre es tan fácil de controlar. Fe cuando diferentes tareas quieren acceder a los mismos recursos, como intentar cambiar la misma variable en diferentes subprocesos o acceder a los recursos ya bloqueados por los diferentes subprocesos.
Hay algunas abstracciones que debemos conocer.
- Colas.
- Rendimiento de tareas sincrónico / asincrónico.
- Prioridades.
- Problemas comunes.
Colas
Debe ser serial o concurrente . Así como global o privada al mismo tiempo.
Con las colas en serie, las tareas se terminarán una por una, mientras que con las colas simultáneas, las tareas se realizarán simultáneamente y se terminarán en horarios inesperados. El mismo grupo de tareas llevará más tiempo en una cola en serie en comparación con una cola simultánea.
Puede crear sus propias colas privadas (tanto en serie como simultáneas ) o utilizar colas globales (del sistema) ya disponibles . La cola principal es la única cola en serie de todas las colas globales .
Se recomienda encarecidamente no realizar tareas pesadas que no estén relacionadas con el trabajo de la interfaz de usuario en la cola principal (por ejemplo, cargar datos de la red), sino realizarlas en las otras colas para mantener la interfaz de usuario descongelada y receptiva a las acciones del usuario. Si permitimos que se cambie la interfaz de usuario en las otras colas, los cambios se pueden realizar en un horario y velocidad diferentes e inesperados. Algunos elementos de la interfaz de usuario se pueden dibujar antes o después de que se necesiten. Puede bloquear la interfaz de usuario. También debemos tener en cuenta que, dado que las colas globales son colas del sistema, el sistema puede ejecutar algunas otras tareas en ellas.
Calidad de servicio / prioridad
Las colas también tienen diferentes qos (Calidad de servicio) que establecen la prioridad de ejecución de la tarea (de mayor a menor aquí):
.userInteractive - cola principal
.userInitiate - para las tareas iniciadas por el usuario en las que el usuario espera alguna respuesta
.utility - para las tareas que lleva algo de tiempo y no requiere una respuesta inmediata, por ejemplo, trabajar con datos
.background - para las tareas que no están relacionadas con la parte visual y que no son estrictas para el tiempo de finalización).
También hay
una cola .default que no transfiere la información de qos . Si no fuera posible detectar los qos la qos utilizará entre .userInitiate y .utility .
Las tareas se pueden realizar de forma sincrónica o asincrónica .
Sincrónico función devuelve el control a la cola actual solo después de que finaliza la tarea. Bloquea la cola y espera hasta que finalice la tarea.
Asincrónico función devuelve el control a la cola actual justo después de que se haya enviado la tarea para que se realice en la cola diferente. No espera hasta que termine la tarea. No bloquea la cola.
Problemas comunes.
Los errores más populares que cometen los programadores al proyectar las aplicaciones simultáneas son los siguientes:
- Condición de carrera : se produce cuando la aplicación funciona depende del orden de ejecución de las partes del código.
- Inversión de prioridad : cuando las tareas de mayor prioridad esperan a que finalicen las tareas de menor prioridad debido al bloqueo de algunos recursos
- Interbloqueo : cuando algunas colas tienen una espera infinita de las fuentes (variables, datos, etc.) ya bloqueadas por algunas de estas colas.
NUNCA llame a la función de sincronización en la cola principal .
Si llama a la función de sincronización en la cola principal, bloqueará la cola y la cola estará esperando a que se complete la tarea, pero la tarea nunca se terminará ya que ni siquiera podrá comenzar debido a que la cola es ya bloqueado. Se llama punto muerto .
¿Cuándo usar la sincronización?
Cuando necesitamos esperar hasta que finalice la tarea. Fe cuando nos aseguramos de que alguna función / método no se llame doblemente. Tenemos sincronización y estamos tratando de evitar que se llame dos veces hasta que esté completamente terminado. Aquí hay un código para esta preocupación:
¿Cómo averiguar qué causó el informe de bloqueo de errores en el dispositivo IOS?
DispatchQueue.main.sync
desde un hilo en segundo plano?