¿Cuándo no es una buena idea el multihilo? [cerrado]


Recientemente estuve trabajando en una aplicación que enviaba y recibía mensajes a través de Ethernet y Serial. Luego me encargaron agregar el monitoreo de los discretos de DIO. I throught,

" No hay razón para interrumpir el hilo que está involucrado en el mensaje procesando, voy a crear otro hilo que monitorea a DIO."

Esta decisión, sin embargo, resultó ser pobre. A veces el hilo principal se interrumpiría entre un Enviar y recibir un mensaje serie. Esta interrupción interrumpiría el tiempo y, por desgracia, los mensajes se perderían (para siempre).

Encontré otra manera de monitorear el DIO sin usar otro hilo y la comunicación Ethernet y Serial se restauraron a su funcionalidad correcta.

Todo el fiasco, sin embargo, me hizo pensar. Son sus pautas generales sobre cuándo no usar múltiples hilos y / o alguien tiene más ejemplos de situaciones cuando el uso de múltiples hilos no es una buena idea?

* * EDITAR: Basado en sus comentarios y después de buscar información en Internet, he compuesto una entrada de blog titulada ¿Cuándo no es una buena idea el multihilo?

Author: CodingWithoutComments, 2008-09-18

14 answers

  1. En una máquina de un solo procesador y una aplicación de escritorio, utiliza subprocesos múltiples para que no congele la aplicación, pero para nada más.
  2. En un solo servidor de procesador y una aplicación basada en web, no hay necesidad de subprocesos múltiples porque el servidor web maneja la mayor parte.
  3. En una máquina multiprocesador y aplicación de escritorio, se sugiere utilizar subprocesos múltiples y programación paralela. Haz tantos hilos como procesadores haya.
  4. En un servidor multiprocesador y una web aplicación basada, no hay necesidad de nuevo para subprocesos múltiples porque el servidor web lo maneja.

En total, si utiliza varios subprocesos para otras aplicaciones de escritorio que no sean descongelar y cualquier otra respuesta genérica, hará que la aplicación sea más lenta si tiene una sola máquina central debido a que los subprocesos se interrumpen entre sí.

¿Por qué? Debido a los interruptores de hardware. Toma tiempo para que el hardware cambie entre hilos en total. En una caja de varios núcleos, siga adelante y use 1 hilo para cada uno core y verás en gran medida una rampa hacia arriba.

 14
Author: SpoiledTechie.com,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-02-01 15:17:19

Parafraseando una cita antigua: Un programador tenía un problema. Pensó: "Lo sé, usaré hilos."Ahora el programador tiene dos problemas. (A menudo atribuido a JWZ, pero parece ser anterior a su uso hablando de expresiones regulares.)

Una buena regla general es "No usar hilos, a menos que haya una razón muy convincente para usar hilos."Múltiples hilos están pidiendo problemas. Trate de encontrar una buena manera de resolver el problema sin usar varios hilos, y solo vuelva a usar hilos si evitar es tanto problema como el esfuerzo extra para usar hilos. Además, considere cambiar a varios subprocesos si se está ejecutando en una máquina multi-núcleo / multi-CPU, y las pruebas de rendimiento de la versión de subproceso único muestran que necesita el rendimiento de los núcleos adicionales.

 6
Author: Thomee,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-09-18 16:10:12

Multi-threading es una mala idea si:

  • Varios subprocesos acceden y actualizan el mismo recurso (establece una variable, escribe en un archivo), y no entiendes thread safety.

  • Varios subprocesos interactúan entre sí y no entiendes mutexes y herramientas de gestión de subprocesos similares.

  • El programa utiliza variables estáticas (los hilos suelen compartirlas de forma predeterminada).

  • No ha depurado la concurrencia cuestión.

 6
Author: Adam Liss,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-11-10 05:48:48

En realidad, el subproceso múltiple no es escalable y es difícil de depurar, por lo que no debe usarse en ningún caso si puede evitarlo. Hay pocos casos en los que es obligatorio : cuando el rendimiento en una CPU múltiple importa, o cuando se trata de un servidor que tiene muchos clientes que tardan mucho tiempo en responder.

En cualquier otro caso, puede usar alternativas como trabajos queue + cron o bien.

 4
Author: e-satis,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-09-18 16:00:17

Es posible que desee echar un vistazo a la página web de Dan Kegel " El problema C10K" sobre el manejo de múltiples fuentes/sumideros de datos.

Básicamente es mejor usar subprocesos mínimos, que en sockets se pueden hacer en la mayoría de los sistemas operativos con algún sistema de eventos (o asincrónicamente en Windows usando IOCP).

Cuando se encuentra con el caso en el que el sistema operativo y / o las bibliotecas no ofrecen una forma de realizar la comunicación de una manera no bloqueante, es mejor usar un grupo de subprocesos para manejarlos mientras reportando al mismo bucle de eventos.

Ejemplo de diagrama de diseño:

Per CPU [*] EVENTLOOP   ------ Handles nonblocking I/O using OS/library utilities
                       |                        \___  Threadpool for various blocking events
                       Threadpool for handling the I/O messages that would take long
 3
Author: harningt,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-09-18 16:40:00

Multi-threading no es una buena idea si necesita garantizar una sincronización física precisa (como en su ejemplo). Otros contras incluyen el intercambio intensivo de datos entre hilos. Yo diría que multi-threading es bueno para tareas realmente paralelas si no te importa mucho su velocidad relativa / prioridad / tiempo.

 2
Author: Michael Pliskin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-09-18 16:04:06

Una aplicación reciente que escribí que tenía para usar multithreading (aunque no unbounded number of threads) fue una en la que tuve que comunicarme en varias direcciones a través de dos protocolos, además de monitorear un tercer recurso para los cambios. Ambas bibliotecas de protocolos requerían un subproceso para ejecutar el bucle de eventos respectivo, y cuando se tenían en cuenta, era fácil crear un tercer bucle para la supervisión de recursos. Además de los requisitos de bucle de eventos, los mensajes que pasan por el los cables tenían estrictos requisitos de sincronización, y un bucle no podía arriesgarse a bloquear el otro, algo que se alivió aún más mediante el uso de una CPU multinúcleo (SPARC).

Hubo más discusiones sobre si cada procesamiento de mensajes debería considerarse un trabajo que se le dio a un subproceso de un grupo de subprocesos, pero al final era una extensión que no valía la pena el trabajo.

All-in-all, los subprocesos solo deberían considerarse si es posible cuando se puede particionar el trabajo en trabajos (o series de trabajos) de modo que la semántica sea relativamente fácil de documentar e implementar, y se puede poner un límite superior en el número de subprocesos que se utilizan y que necesitan interactuar. Los sistemas donde esto se aplica mejor son casi sistemas de paso de mensajes.

 2
Author: larsivi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-09-18 16:10:39

Multithreading es malo excepto en el caso único donde es bueno. Este caso es

  1. El trabajo está enlazado a la CPU, o partes de él están enlazadas a la CPU
  2. La obra es paralelizable.

Si falta una o ambas de estas condiciones, multithreading no va a ser una estrategia ganadora.

Si el trabajo no está enlazado a la CPU, entonces no está esperando en subprocesos para terminar el trabajo, sino más bien por algún evento externo, como la actividad de red, para que el proceso se complete su trabajo. Usando hilos, existe el costo adicional de los cambios de contexto entre hilos, el costo de la sincronización (mutexes, etc.) y la irregularidad de la preempción del hilo. La alternativa en el uso más común es IO asíncrono, en el que un solo hilo escucha varios puertos io y actúa sobre lo que esté listo ahora, uno a la vez. Si por alguna casualidad estos canales lentos todos pasan a estar listos al mismo tiempo, puede parecer que experimentará una desaceleración, pero en práctica esto rara vez es cierto. El costo de manejar cada puerto individualmente a menudo es comparable o mejor que el costo de sincronizar el estado en múltiples hilos a medida que cada canal se vacía.

Muchas tareas pueden estar vinculadas a la computación, pero aún no es práctico usar un enfoque multiproceso porque el proceso debe sincronizarse en todo el estado. Tal programa no puede beneficiarse de multithreading porque ningún trabajo se puede realizar simultáneamente. Afortunadamente, la mayoría de los programas que requieren enormes las cantidades de CPU se pueden paralelizar a algún nivel.

 2
Author: SingleNegationElimination,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-06-08 18:15:08

In priciple everytime there is no overhead for the caller to wait in a queue.

 1
Author: Claus Thomsen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-09-18 16:01:25

Un par más de posibles razones para usar hilos:

  1. Su plataforma carece de operaciones de E/S asincrónicas, por ejemplo, Windows ME (Sin puertos de finalización o E/S superpuestas, un dolor al portar aplicaciones XP que las utilizan.) Java 1.3 y anteriores.
  2. Una función de biblioteca de terceros que puede colgarse, por ejemplo, si un servidor remoto está inactivo, y la biblioteca no proporciona forma de cancelar la operación y no puede modificarla.

Mantener una interfaz gráfica de usuario sensible durante el procesamiento intensivo no siempre requieren hilos adicionales. Una sola función de devolución de llamada suele ser suficiente.

Si nada de lo anterior se aplica y todavía quiero paralelismo por alguna razón, prefiero lanzar un proceso independiente si es posible.

 1
Author: finnw,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-09-18 17:52:34

Yo diría que el multi-threading se usa generalmente para:

  1. Permitir el procesamiento de datos en segundo plano mientras una interfaz gráfica de usuario sigue siendo sensible
  2. Divida el análisis de datos muy grandes en varias unidades de procesamiento para que pueda obtener sus resultados más rápido.
  3. Cuando está recibiendo datos de algún hardware y necesita algo para agregarlos continuamente a un búfer mientras que algún otro elemento decide qué hacer con él (escribir en el disco, mostrar en una interfaz gráfica de usuario, etc.).

Así que si no estás al resolver uno de esos problemas, es poco probable que agregar hilos te haga la vida más fácil. De hecho, es casi seguro que lo hará más difícil porque, como otros han mencionado; la depuración de aplicaciones multithreaded es considerablemente más trabajo que una solución de un solo subproceso.

La seguridad podría ser una razón para evitar el uso de múltiples subprocesos (sobre múltiples procesos). Consulte Google chrome para ver un ejemplo de funciones de seguridad multiproceso.

 1
Author: Jon Cage,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-09-18 18:39:46

Multi-threading es escalable, y le permitirá a su interfaz de usuario mantener su responsivness mientras hace cosas muy complicadas en segundo plano. No entiendo dónde otras respuestas están adquiriendo su información en multi-threading.

When you should not multi-thread es una pregunta que lleva mal a tu problema. Su problema es el siguiente: ¿Por qué el multi-threading de mi aplicación causó que las comunicaciones serie / ethernet fallaran?

La respuesta a esa pregunta dependerá de la aplicación, que debería examinarse en otra cuestión. Sé que es un hecho que puede tener comunicaciones ethernet y serie en una aplicación multiproceso al mismo tiempo que muchas otras tareas sin causar ninguna pérdida de datos.

La única razón para no usar multi-threading es:

  1. Hay una tarea, y ninguna interfaz de usuario con la que la tarea interferirá.

Las razones para usar mutli-threading son:

  1. Proporciona superior respuesta al usuario
  2. Realiza múltiples tareas al mismo tiempo para disminuir el tiempo total de ejecución
  3. Utiliza más de las CPU multi-core actuales, y multi-multi-core del futuro.

Hay tres métodos básicos de programación multihilo que hacen que la seguridad del hilo se implemente con facilidad , solo necesita usar uno para tener éxito:

  1. Tipos de datos seguros de subprocesos pasados entre subprocesos.
  2. Métodos seguros de subprocesos en el objeto subproceso a modificar datos pasados entre.
  3. Capacidades de postMessage para comunicarse entre hilos.
 1
Author: Kieveli,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-06-08 18:17:51

¿Los procesos son paralelos? ¿El rendimiento es una preocupación real? ¿Hay múltiples 'hilos' de ejecución como en un servidor web? No creo que haya una respuesta finita.

 0
Author: Greg Ogle,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-09-18 16:01:55

Una fuente común de problemas de subprocesamiento son los enfoques habituales empleados para sincronizar datos. Hacer que los subprocesos compartan el estado y luego implementen el bloqueo en todos los lugares apropiados es una fuente importante de complejidad tanto para el diseño como para la depuración. Conseguir el bloqueo adecuado para equilibrar la estabilidad, el rendimiento y la escalabilidad siempre es un problema difícil de resolver. Incluso los expertos más experimentados se equivocan con frecuencia. Las técnicas alternativas para lidiar con el roscado pueden aliviar gran parte de esto complejidad. El lenguaje de programación Clojure implementa varias técnicas interesantes para tratar con la concurrencia.

 0
Author: Todd Stout,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-06-08 17:56:27