28

He buscado 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.Grand Central Dispatch vs NSThreads?

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é alguna vez sería preferible a la rosca tradicional? ¿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.

+0

Sólo una nota: GCD permite el uso de funciones si se prefiere sobre los bloques. – Monolo

+0

Hay videos realmente buenos sobre Apple Developer Connection (gratis) sobre este tema. ¡Compruébalo! – Jay

Respuesta

44

Ventajas de Despacho

Las ventajas de expedición son en su mayoría describen aquí:

Migrating Away from Threads

La idea es que se elimina el trabajo de su parte, ya que el paradigma se ajusta código más con más facilidad .

  • Reduce la pena de memoria de la aplicación de la pena para el almacenamiento de las pilas de subprocesos en el espacio de memoria de la aplicación.
  • Elimina el código necesario para crear y configurar sus hilos.
  • Elimina el código necesario para administrar y programar el trabajo en subprocesos.
  • Simplifica el código que tiene que escribir.

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

Ventajas de hilos

¿Por qué seguir utilizando hilos? Desde el mismo documento:

Es importante recordar que las colas no son una panacea para hilos que sustituyen. El modelo de programación asíncrona ofrecido por 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 de en momentos específicos. Por lo tanto, los hilos siguen siendo una opción más en los casos en que se necesita una latencia mínima, como , 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). Edit: 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 sintaxis horrible (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 :)

Puedes encontrar my examples from here útil, o simplemente distrayendo No es seguro.

+0

[Documentos] (https://developer.apple.com/reference/dispatch?changes=latest_minor) dice ** "El trabajo enviado a las colas de envío se ejecuta en un grupo de hilos totalmente administrado por el sistema. No se garantiza como al hilo en el que se ejecuta una tarea "**, ¿Qué quieren decir en la última línea? – Rishi

9

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 "extraña sintaxis" es porque eligieron el símbolo de intercalación (^), ya que era uno de los pocos símbolos que no estaba sobrecargado como un 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, usted tiene que escribir el código tanto para el trabajo que desea realizar como para la creación y gestión de los hilos en sí . Las colas de envío permiten que se concentre en el trabajo que realmente desea realizar sin tener que preocuparse por la creación y administración del subproceso . En cambio, el sistema maneja toda la creación y gestión de subprocesos por usted. La ventaja de es que el sistema puede gestionar mucho más 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 es , por lo general, puede comenzar a ejecutar su tarea más rápido de lo que podría si usted mismo ha creado el hilo.

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

...

Aunque estaría en lo correcto al señalar que dos tareas que se ejecutan en una cola de serie no se ejecutan al mismo tiempo, hay que recordar que si dos hilos toman un bloqueo al mismo tiempo, cualquier concurrencia ofrecido por los hilos se pierde o se reduce significativamente. Lo que es más importante, el modelo roscado requiere la creación de dos hilos, que toman tanto en el kernel como en la memoria de espacio de usuario. Las colas de envío no pagan la misma penalización de memoria para sus subprocesos, y los subprocesos que utilizan se mantienen ocupados y no bloqueados.

+0

No sigo este último párrafo. Siempre parece que el bloqueo ocasional es peor que una cola en serie sin concurrencia en absoluto. ¿No es una pregunta empírica, dependiendo de qué tan seguido ocurre el bloqueo en tu código? –

+1

Creo que eso es lo que está diciendo, incluso si usa una cola en serie, a menudo es mejor que las secuencias simultáneas con bloqueo. Es "a menudo" y no "siempre" porque si el bloqueo es mínimo (y puede evitar el bloqueo, etc.), podría ser más rápido con la concurrencia pero con la sobrecarga de la memoria de subprocesos. – bryanmac

+1

Además, la gran mayoría de las veces con subprocesos, la gente simplemente intenta sincronizarse y no bloquear el subproceso de la interfaz de usuario, que es una buena cola simple. – bryanmac

11

Mientras que las respuestas hasta el momento son aproximadamente el contexto de las discusiones 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 se debe preferir GCD es debido a entornos multitarea (ya que están en MacOSX y no en iOS). Los hilos están bien si su aplicación se está ejecutando solo 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, abre un programa de edición de imagen y juega con una imagen de alta resolución, decide aplicar un filtro de imagen especial y su aplicación de imagen siendo inteligente detecta que tiene ocho núcleos y comienza 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, consulte 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.

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.

+0

Muy interesante +1. –

+0

Sí, muy buenos puntos. gracias – bryanmac

+0

No estoy seguro de enhebrar modelos y núcleos, pero la evidencia empírica es que incluso en iOS, el modelo de bloqueo para GCD es mucho más rápido que mi favorito, '@ synchronized': http://www.fieryrobot.com/blog/2010/09/01/synchronisation-using-grand-central-dispatch/comment-page-1/# comment-221262 (ignore los consejos del autor de utilizar setters asíncronos si no se aplican a su caso) –

0

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 sobre hilos:

Cuantos trabajos están haciendo los núcleos de su CPU Cuantos núcleos de CPU tiene. Cuantos hilos deberían engendrarse. Si GCD lo necesita, puede ir al núcleo y comunicar sobre los recursos, por lo tanto, una mejor programación. Menos carga en el núcleo 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 EN http://iosdose.com

Cuestiones relacionadas