tutorials tutorial example objective-c multithreading macos cocoa grand-central-dispatch

objective c - tutorial - Grand Central Dispatch vs NSThreads?



nsoperationqueue swift 3 example (4)

GCD (Grand Central Dispatch): GCD proporciona y gestiona colas FIFO a las que su aplicación puede enviar tareas en forma de objetos de bloque. El trabajo enviado a las colas de envío se ejecuta en un conjunto de hilos totalmente gestionados por el sistema. No se garantiza el hilo sobre el que se ejecuta una tarea. Por qué GCD over threads:

Cuánto trabajo están haciendo los núcleos de su CPU Cuántos núcleos de CPU tiene. ¿Cuántos hilos deberían engendrarse? Si GCD lo necesita, puede ir al kernel y comunicarse sobre los recursos, por lo tanto, una mejor programación. Menos carga en kernel y mejor sincronización con OS GCD usa subprocesos existentes del grupo de subprocesos en lugar de crear y luego destruir. La mejor ventaja de los recursos de hardware del sistema, al tiempo que permite que el sistema operativo equilibre la carga de todos los programas que se ejecutan actualmente con consideraciones como el calentamiento y la duración de la batería.

He compartido mi experiencia con hilos, sistema operativo y GCD AT http://iosdose.com

Busqué una variedad de fuentes pero realmente no entiendo la diferencia entre usar NSThreads y GCD. Soy completamente nuevo en la plataforma OS X, así que podría malinterpretarlo por completo.

De lo que leo en línea, GCD parece hacer exactamente lo mismo que los hilos básicos (POSIX, NSThreads , etc.) y agrega mucha más jerga técnica ("bloques"). Parece complicar demasiado el sistema básico de creación de hilos (crear hilo, ejecutar la función).

¿Qué es exactamente GCD y por qué sería preferible a los hilos tradicionales? ¿Cuándo se deben usar los hilos tradicionales en lugar de GCD? Y finalmente, ¿hay alguna razón para la extraña sintaxis de GCD? ("bloques" en lugar de simplemente llamar funciones).

Estoy en Mac OS X 10.6.8 Snow Leopard y no estoy programando para iOS. Estoy programando para Mac. Estoy usando Xcode 3.6.8 en Cocoa, creando una aplicación GUI.


Los bloques permiten pasar un bloque de código para ejecutar. Una vez que superas la "sintaxis extraña", son bastante poderosos.

GCD también utiliza colas que, si se usan correctamente, pueden ayudar con la simultaneidad de bloqueo si el código que se ejecuta en las colas separadas está aislado. Es una forma más sencilla de ofrecer fondo y concurrencia mientras se minimiza la posibilidad de que se produzcan interbloqueos (si se usan correctamente).

La "sintaxis extraña" se debe a que eligieron el símbolo de intercalación (^) porque era uno de los pocos símbolos que no estaba sobrecargado como operador en C ++

Ver: https://developer.apple.com/library/ios/#documentation/General/Conceptual/ConcurrencyProgrammingGuide/OperationQueues/OperationQueues.html

Cuando se trata de agregar concurrencia a una aplicación, las colas de envío proporcionan varias ventajas sobre los subprocesos. La ventaja más directa es la simplicidad del modelo de programación de cola de trabajo. Con los hilos, debe escribir el código para el trabajo que desea realizar y para la creación y administración de los hilos. Las colas de envío le permiten concentrarse en el trabajo que realmente desea realizar sin tener que preocuparse por la creación y gestión del hilo. En cambio, el sistema maneja toda la creación y gestión de subprocesos por usted. La ventaja es que el sistema puede gestionar subprocesos de manera mucho más eficiente que cualquier otra aplicación. El sistema puede escalar el número de subprocesos dinámicamente en función de los recursos disponibles y las condiciones actuales del sistema. Además, el sistema generalmente puede comenzar a ejecutar su tarea más rápido de lo que podría hacerlo si creara el hilo usted mismo.

Aunque podría pensar que volver a escribir su código para las colas de despacho sería difícil, a menudo es más fácil escribir código para las colas de despacho que escribir código para subprocesos. La clave para escribir su código es diseñar tareas que sean autónomas y puedan ejecutarse de forma asíncrona. (Esto es realmente cierto tanto para los hilos como para las colas de despacho).

...

Aunque estaría en lo cierto al señalar que dos tareas que se ejecutan en una cola serie no se ejecutan al mismo tiempo, debe recordar que si dos subprocesos toman un bloqueo al mismo tiempo, cualquier concurrencia ofrecida por los subprocesos se pierde o se reduce significativamente. Más importante aún, el modelo con subprocesos requiere la creación de dos subprocesos, que ocupan tanto la memoria del kernel como la del espacio de usuario. Las colas de envío no pagan la misma penalización de memoria para sus subprocesos, y los subprocesos que usan se mantienen ocupados y no bloqueados.


Si bien las respuestas hasta ahora son sobre el contexto de subprocesos vs GCD dentro del dominio de una sola aplicación y las diferencias que tiene para la programación, la razón por la que siempre debes preferir GCD es debido a los entornos multitarea (ya que estás en MacOSX y no en iOS) . Los hilos están bien si su aplicación se ejecuta sola en su máquina. Supongamos que tiene un programa de edición de video y desea aplicar algún efecto al video. La renderización tardará 10 minutos en una máquina con ocho núcleos. Multa.

Ahora, mientras la aplicación de video se agita en segundo plano, abres un programa de edición de imagen y juegas con una imagen de alta resolución, decides aplicar algún filtro de imagen especial y tu aplicación de imagen es inteligente. Detecta que tienes ocho núcleos e inicia ocho hilos para procesar la imagen. Niza ¿no? Excepto que es terrible para el rendimiento. La aplicación de edición de imágenes no sabe nada sobre la aplicación de video (y viceversa) y, por lo tanto, ambas solicitarán su número óptimo de subprocesos. Y habrá dolor y sangre mientras los núcleos intentan cambiar de un hilo a otro, porque para evitar la inanición, la CPU finalmente permitirá que todos los hilos se ejecuten, aunque en esta situación sería más óptimo ejecutar solo 4 hilos para el video. aplicación y 4 hilos para la aplicación de imagen.

Para obtener una referencia más detallada, eche un vistazo a http://deusty.blogspot.com/2010/11/introducing-gcd-based-cocoahttpserver.html donde puede ver un punto de referencia de un servidor HTTP usando GCD versus hilo, y vea cómo se escala. Una vez que comprenda el problema que tienen los hilos para máquinas multinúcleo en entornos de aplicaciones múltiples, siempre querrá usar GCD, simplemente porque los hilos no siempre son óptimos, mientras que GCD potencialmente puede serlo ya que el sistema operativo puede escalar el uso de hilo por aplicación dependiendo de la carga.

Por favor, recuerde que no tendremos más GHz en nuestras máquinas en el corto plazo. A partir de ahora solo tendremos más núcleos, por lo que es su deber utilizar la mejor herramienta para este entorno, y ese es GCD.


Ventajas del envío

Las ventajas del envío se describen principalmente aquí:

Migrando lejos de hilos

La idea es que elimines el trabajo de tu parte, ya que el paradigma se ajusta más al código más fácilmente.

  • Reduce la pena de memoria que su aplicación paga por almacenar pilas de subprocesos en el espacio de memoria de la aplicación.
  • Elimina el código necesario para crear y configurar tus hilos.
  • Elimina el código necesario para administrar y programar el trabajo en los hilos.
  • Simplifica el código que tienes que escribir.

Empíricamente, usar el bloqueo de tipo GCD en lugar de @synchronized es aproximadamente 80% más rápido o más, aunque los micro-benchmarks pueden ser engañosos. Lea más here , aunque creo que el consejo para sincronizarse con las escrituras no se aplica en muchos casos, y es más lento (pero no es asincrónico).

Ventajas de los hilos

¿Por qué seguirías usando Threads? Del mismo documento:

Es importante recordar que las colas no son una panacea para reemplazar los hilos. El modelo de programación asíncrono que ofrecen las colas es apropiado en situaciones donde la latencia no es un problema. Aunque las colas ofrecen formas de configurar la prioridad de ejecución de las tareas en la cola, las prioridades de ejecución más altas no garantizan la ejecución de tareas en momentos específicos. Por lo tanto, los subprocesos siguen siendo una opción más apropiada en los casos en que se necesita una latencia mínima, como en la reproducción de audio y video.

Otro lugar en el que personalmente no he encontrado una solución ideal para usar colas es en procesos de daemon que deben reprogramarse constantemente. No es que no puedas reprogramarlos, pero el bucle dentro de un método NSThread es más simple (creo). Editar: ahora estoy convencido de que incluso en este contexto, el bloqueo al estilo GCD sería más rápido, y también podría hacer un ciclo dentro de una operación despachada por GCD.

Bloques en Objective-C?

Los bloques son realmente horribles en Objective-C debido a la horrible sintaxis (aunque Xcode a veces puede ayudar con el autocompletado, al menos). Si observa bloques en Ruby (o en cualquier otro idioma, casi) verá cuán simples y elegantes son para despachar operaciones. Diría que te acostumbrarás a la sintaxis de Objective-C, pero realmente creo que te acostumbrarás a copiar mucho de tus ejemplos :)

Puede encontrar mis ejemplos de aquí para ser útil o simplemente distraer. No es seguro.