¿Qué pueden hacer varios hilos que no puede hacer un solo hilo? [cerrado]

100

Si bien los hilos pueden acelerar la ejecución del código, ¿son realmente necesarios? ¿Se puede hacer cada pieza de código usando un solo hilo o hay algo que existe que solo se puede lograr usando múltiples hilos?

Pájaro enojado
fuente
29
Basado en algunas de las respuestas ya publicadas aquí, creo que es necesario aclarar. El propósito del subprocesamiento es permitir que las computadoras (parezcan) hacer más de una cosa a la vez. Si esto se hace usando una computadora con un solo núcleo, no verá ninguna aceleración general. Lo que verás es desbloquear; En un programa de subproceso único, la interfaz de usuario se bloqueará mientras se realizan los cálculos. En un programa de subprocesos múltiples, la interfaz de usuario aún puede utilizarse mientras los cálculos se realizan en segundo plano.
Robert Harvey
11
Por supuesto, si tiene múltiples núcleos de procesador en su computadora (lo cual es común hoy en día), su programa puede usar hilos para aprovechar núcleos adicionales para realizar su procesamiento, y verá una aceleración, porque está arrojando más caballos de fuerza a Su problema informático. Si no usa hilos en absoluto, su programa solo utilizará un núcleo de procesador único, lo cual está bien si eso es todo lo que necesita.
Robert Harvey
14
Un programa de subproceso único no puede bloquear los recursos de la misma manera que un programa de subproceso múltiple.
zzzzBov
3
Respuesta: corre en dos núcleos
Daniel Little
66
Respuesta: causa un punto muerto.
Trabajo

Respuestas:

111

En primer lugar, los hilos no pueden acelerar la ejecución del código. No hacen que la computadora funcione más rápido. Todo lo que pueden hacer es aumentar la eficiencia de la computadora mediante el uso de tiempo que de otra manera se desperdiciaría. En ciertos tipos de procesamiento, esta optimización puede aumentar la eficiencia y disminuir el tiempo de ejecución.

La respuesta simple es sí. Puede escribir cualquier código que se ejecute en un solo hilo. Prueba: un sistema de procesador único solo puede ejecutar instrucciones linealmente. El sistema operativo realiza varias líneas de ejecución, procesa interrupciones, guarda el estado del subproceso actual e inicia otra.

La respuesta compleja es ... ¡más compleja! La razón por la que los programas multiproceso a menudo pueden ser más eficientes que los lineales se debe a un "problema" de hardware. La CPU puede ejecutar cálculos más rápidamente que la memoria y el almacenamiento duro IO. Entonces, una instrucción "agregar", por ejemplo, se ejecuta mucho más rápido que una "búsqueda". Las memorias caché y la búsqueda de instrucciones de programas dedicados (no estoy seguro del término exacto aquí) pueden combatir esto hasta cierto punto, pero el problema de la velocidad persiste.

Subprocesar es una forma de combatir este desajuste mediante el uso de la CPU para las instrucciones vinculadas a la CPU mientras se completan las instrucciones IO. Un plan típico de ejecución de subprocesos probablemente sería: Obtener datos, procesar datos, escribir datos. Suponga que la búsqueda y la escritura toman 3 ciclos y el procesamiento toma uno, con fines ilustrativos. ¿Puedes ver que mientras la computadora lee o escribe, no hace nada durante 2 ciclos cada uno? ¡Claramente está siendo flojo, y necesitamos descifrar nuestro látigo de optimización!

Podemos reescribir el proceso usando subprocesos para usar este tiempo perdido:

  1. # 1 buscar
  2. No operacion
  3. # 2 buscar
  4. # 1 está hecho, procesalo
  5. escribe # 1
  6. # 1 buscar
  7. # 2 está hecho, procesalo
  8. escribir # 2
  9. buscar # 2

Y así. Obviamente, este es un ejemplo un tanto artificial, pero puede ver cómo esta técnica puede utilizar el tiempo que de lo contrario se gastaría esperando IO.

Tenga en cuenta que el enhebrado como se muestra arriba solo puede aumentar la eficiencia en procesos fuertemente vinculados a E / S. Si un programa está calculando principalmente cosas, no habrá muchos "agujeros" en los que podríamos trabajar más. Además, hay una sobrecarga de varias instrucciones al cambiar entre hilos. Si ejecuta demasiados subprocesos, la CPU pasará la mayor parte del tiempo cambiando y no trabajando mucho en el problema. Esto se llama paliza .

Todo eso está muy bien para un procesador de un solo núcleo, pero la mayoría de los procesadores modernos tienen dos o más núcleos. Los subprocesos siguen teniendo el mismo propósito: maximizar el uso de la CPU, pero esta vez tenemos la capacidad de ejecutar dos instrucciones separadas al mismo tiempo. Esto puede disminuir el tiempo de ejecución en función de la cantidad de núcleos disponibles, porque la computadora es realmente multitarea, no cambia de contexto.

Con múltiples núcleos, los hilos proporcionan un método para dividir el trabajo entre los dos núcleos. Sin embargo, lo anterior aún se aplica a cada núcleo individual; Un programa que ejecuta una eficiencia máxima con dos subprocesos en un núcleo probablemente se ejecutará con la máxima eficiencia con aproximadamente cuatro subprocesos en dos núcleos. (La eficiencia se mide aquí mediante ejecuciones mínimas de instrucciones NOP).

Los problemas con la ejecución de subprocesos en múltiples núcleos (a diferencia de un solo núcleo) generalmente son resueltos por el hardware. La CPU se asegurará de bloquear las ubicaciones de memoria apropiadas antes de leer / escribir en ella. (He leído que usa un bit de indicador especial en la memoria para esto, pero esto se puede lograr de varias maneras). Como programador con lenguajes de nivel superior, no tiene que preocuparse por nada más en dos núcleos mientras tendría que ver con uno.

TL; DR: los subprocesos pueden dividir el trabajo para permitir que la computadora procese varias tareas de forma asincrónica. Esto permite que la computadora funcione con la máxima eficiencia al utilizar todo el tiempo de procesamiento disponible, en lugar de bloquearse cuando un proceso está esperando un recurso.

Michael K
fuente
17
Excelente respuesta Solo quería explicar que después de cierto punto, agregar más subprocesos en realidad puede hacer que un programa se ejecute más lentamente , porque se utiliza todo el tiempo "perdido" anteriormente, y ahora solo agrega cambios adicionales de contexto y sobrecarga de sincronización.
Karl Bielefeldt
8
+1 para describir cómo los hilos ayudan con el procesamiento de bloqueo de E / S. Otro uso de los hilos es permitir que la interfaz de usuario continúe procesando las acciones del usuario (movimiento del mouse, barras de progreso, pulsaciones de teclas) para que la percepción del usuario sea que el programa no se ha "congelado".
jqa
3
Una adición más: estrictamente hablando, los hilos no agregan ninguna expresividad a la mayoría de los idiomas; podría, si fuera absolutamente necesario, implementar todos los multiplexados usted mismo y obtener los mismos resultados. Sin embargo, en la práctica, esto equivaldría a volver a implementar toda su biblioteca de subprocesos, al igual que la recursión no es estrictamente necesaria, pero puede emularse escribiendo su propia pila de llamadas.
Kilian Foth
99
@james: clasificaría el procesamiento de IU como solo otra forma de E / S. Quizás lo peor, ya que los usuarios tienden a ser lentos y no lineales. :)
TMN
77
Hay una suposición silenciosa en la pregunta y la respuesta en torno a la computadora como un solo núcleo o CPU. Mi reloj tiene dos núcleos, dudo que la suposición sea válida en cualquier máquina moderna.
blueberryfields
37

¿Qué pueden hacer varios hilos que no puede hacer un solo hilo?

Nada.

Bosquejo de prueba simple:

  • [Conjetura de Turing de la Iglesia] ⇒ Todo lo que se puede calcular puede ser calculado por una Máquina de Turing Universal.
  • Una máquina universal de Turing es de un solo hilo.
  • Ergo, todo lo que se puede calcular se puede calcular con un solo hilo.

Sin embargo, tenga en cuenta que hay una gran suposición oculta allí: a saber, que el lenguaje utilizado dentro del hilo único es Turing completo.

Entonces, la pregunta más interesante sería: "¿Puede agregar solo subprocesos múltiples a un lenguaje que no sea Turing completo hacer que Turing sea completo?" Y creo que la respuesta es "Sí".

Tomemos los lenguajes funcionales totales. [Para aquellos que no están familiarizados: al igual que la programación funcional es programar con funciones, la programación funcional total es programar con funciones totales.]

Total de los lenguajes funcionales, obviamente, no son Turing-completo: no se puede escribir un bucle infinito en un TFPL (de hecho, eso es más o menos la definición de "total"), pero se puede en una máquina de Turing, ergo existe al menos un programa que no se puede escribir en un TFPL pero sí en un UTM, por lo tanto, los TFPL son menos potentes desde el punto de vista computacional que los UTM.

Sin embargo, tan pronto como agregue subprocesos a un TFPL, obtendrá bucles infinitos: solo haga cada iteración del bucle en un nuevo subproceso. Cada subproceso individual siempre devuelve un resultado, por lo tanto, es Total, pero cada subproceso también genera un nuevo subproceso que ejecuta la siguiente iteración, hasta el infinito.

Yo creo que este lenguaje sería Turing completo.

Como mínimo, responde a la pregunta original:

¿Qué pueden hacer varios hilos que no puede hacer un solo hilo?

Si tiene un lenguaje que no puede hacer bucles infinitos, entonces el subprocesamiento múltiple le permite hacer bucles infinitos.

Tenga en cuenta, por supuesto, que generar un hilo es un efecto secundario y, por lo tanto, nuestro lenguaje extendido no solo ya no es Total, sino que ya ni siquiera es Funcional.

Jörg W Mittag
fuente
13
Como trajiste una "prueba", no puedo evitar "bueno, en realidad ...". Creo que estás abusando de la noción de computabilidad. La prueba es algo lindo y entiendo su punto, pero no está realmente en el nivel de abstracción correcto. No poder hacer las cosas no es lo mismo que no poder calcular , por ejemplo, no puede usar su prueba para decir, porque la máquina Turing puede calcular "todas las funciones computables", puede hacerlo en 3 segundos. Estrictamente hablando, una máquina de un solo subproceso sin interrupciones no puede acceder a E / S mientras mantiene su procesador ocupado haciendo cálculos.
xmm0
1
Y, ninguna computadora real es una máquina de Turing.
Jens
1
@ColeJohnson: Un punto muerto es un detalle de implementación. La salida visible "no se detiene", lo que se puede hacer fácilmente con un solo hilo.
Heinzi
1
@Heinzi: "fácilmente factible" es un eufemismo. Si no recuerdo mal, el segundo o el tercer programa que alguna vez escribí hizo exactamente eso! ;-)
Joachim Sauer
1
Si el universo es de un solo hilo , ¿qué es la teoría de cuerdas ? No se puede discutir con la ciencia como esta.
corsiKa
22

En teoría, todo lo que hace un programa multiproceso también se puede hacer con un programa de subproceso único, solo que más lento.

En la práctica, la diferencia de velocidad puede ser tan grande que no hay forma de utilizar un programa de subproceso único para la tarea. Por ejemplo, si tiene un trabajo de procesamiento de datos por lotes ejecutándose todas las noches, y tarda más de 24 horas en terminar en un solo hilo, no tiene otra opción que hacerlo multiproceso. (En la práctica, el umbral es probablemente aún menor: a menudo, dichas tareas de actualización deben finalizar antes de la mañana, antes de que los usuarios comiencen a usar el sistema nuevamente. Además, otras tareas pueden depender de ellas, que también deben finalizar durante la misma noche. el tiempo de ejecución disponible puede ser tan bajo como unas pocas horas / minutos).

Hacer trabajo informático en múltiples hilos es una forma de procesamiento distribuido; Usted está distribuyendo el trabajo en múltiples hilos. Otro ejemplo de procesamiento distribuido (usando múltiples computadoras en lugar de múltiples hilos) es el protector de pantalla SETI: procesar tantos datos de medición en un solo procesador tomaría mucho tiempo y los investigadores preferirían ver los resultados antes de la jubilación ;-) Sin embargo, no tienen el presupuesto para alquilar una supercomputadora durante tanto tiempo, por lo que distribuyen el trabajo en millones de PC domésticas, para que sea barato.

Péter Török
fuente
El protector de pantalla SETI es un ejemplo de subprocesos en el sentido de que se ejecuta en un subproceso de fondo en su computadora; aún puede hacer otras cosas en su computadora mientras está procesando datos en segundo plano. Sin el hilo, habría una pausa mientras el protector de pantalla SETI realiza sus cálculos; tendrías que esperar a que termine antes de poder continuar tu propio trabajo.
Robert Harvey
3
@Robert: Creo que Péter está utilizando SETI @ Home para explicar el concepto de dividir el trabajo para ejecutar en múltiples procesadores. La computación distribuida es, por supuesto, diferente a la multiproceso, pero el concepto es similar.
Steven
55
Creo que el ejemplo SETI es computación distribuida en lugar de multiproceso. Conceptos similares pero no lo mismo.
11

Aunque los hilos parecen ser un pequeño paso de la computación secuencial, de hecho, representan un gran paso. Descartan las propiedades más esenciales y atractivas de la computación secuencial: comprensibilidad, previsibilidad y determinismo. Los subprocesos, como modelo de cálculo, son tremendamente no deterministas, y el trabajo del programador se convierte en el de podar ese no determinismo.

- El problema con hilos (www.eecs.berkeley.edu/Pubs/TechRpts/2006/EECS-2006-1.pdf).

Si bien hay algunas ventajas de rendimiento que se pueden obtener al usar hilos en los que puede distribuir el trabajo en múltiples núcleos, a menudo tienen un excelente precio.

Una de las desventajas del uso de subprocesos no mencionados aún aquí es la pérdida de compartimentación de recursos que se obtiene con espacios de proceso de subproceso único. Por ejemplo, supongamos que se encuentra con el caso de una segfault. Es posible, en algunos casos, recuperarse de esto en una aplicación multiproceso, ya que simplemente deja morir al niño con fallas y reaparece uno nuevo. Este es el caso en el backend prefork de Apache. Cuando una instancia de httpd se arruina, el peor de los casos es que la solicitud HTTP en particular puede descartarse para ese proceso, pero Apache genera un nuevo hijo y, a menudo, la solicitud solo se reenvía y se atiende. El resultado final es que Apache en su conjunto no se elimina con el hilo defectuoso.

Otra consideración en este escenario son las pérdidas de memoria. Hay algunos casos en los que puede manejar con gracia un bloqueo de subproceso (en UNIX, es posible recuperarse de algunas señales específicas, incluso segfault / fpviolation), pero incluso en ese caso, puede haber perdido toda la memoria asignada por ese subproceso (malloc, nuevo, etc.). Por lo tanto, aunque el proceso puede continuar, pierde cada vez más memoria con el tiempo con cada falla / recuperación. Una vez más, hay algunas formas de minimizar esto, como el uso de agrupaciones de memoria de Apache. Pero esto todavía no protege contra la memoria que podría haber sido asignada por librerías de terceros que el hilo podría haber estado usando.

Y, como han señalado algunas personas, comprender las primitivas de sincronización es quizás lo más difícil de entender. Este problema en sí mismo, solo obtener la lógica general correcta para todo su código, puede ser un gran dolor de cabeza. Los puntos muertos misteriosos son propensos a suceder en los momentos más extraños, y a veces ni siquiera hasta que su programa se haya ejecutado en producción, lo que hace que la depuración sea aún más difícil. Agregue a esto el hecho de que las primitivas de sincronización a menudo varían ampliamente con la plataforma (Windows vs. POSIX), y la depuración a menudo puede ser más difícil, así como la posibilidad de condiciones de carrera en cualquier momento (inicio / inicialización, tiempo de ejecución y apagado), La programación con hilos realmente tiene poca piedad para los principiantes. E incluso para expertos, Todavía hay poca misericordia solo porque el conocimiento del enhebrado en sí no minimiza la complejidad en general. Cada línea de código enhebrado a veces parece agravar exponencialmente la complejidad general del programa y también aumenta la probabilidad de que surja un punto muerto oculto o una extraña condición de carrera en cualquier momento. También puede ser muy difícil escribir casos de prueba para descubrir estas cosas.

Es por eso que algunos proyectos como Apache y PostgreSQL están en su mayor parte basados ​​en procesos. PostgreSQL ejecuta cada subproceso de fondo en un proceso separado. Por supuesto, esto todavía no alivia el problema de la sincronización y las condiciones de carrera, pero agrega bastante protección y de alguna manera simplifica las cosas.

Múltiples procesos que ejecutan cada uno un solo subproceso de ejecución pueden ser mucho mejores que múltiples subprocesos que se ejecutan en un solo proceso. Y con la llegada de gran parte del nuevo código de igual a igual como AMQP (RabbitMQ, Qpid, etc.) y ZeroMQ, es mucho más fácil dividir subprocesos en diferentes espacios de proceso e incluso máquinas y redes, lo que simplifica enormemente las cosas. Pero aún así, no es una bala de plata. Todavía hay complejidad con la que lidiar. Simplemente mueve algunas de sus variables del espacio de procesos a la red.

La conclusión es que la decisión de ingresar al dominio de hilos no es ligera. Una vez que pisas ese territorio, casi instantáneamente todo se vuelve más complejo y nuevas razas de problemas entran en tu vida. Puede ser divertido y genial, pero es como la energía nuclear: cuando las cosas van mal, pueden ir mal y rápido. Recuerdo haber tomado una clase de entrenamiento en criticidad hace muchos años y mostraron fotos de algunos científicos en Los Alamos que jugaban con plutonio en los laboratorios de la Segunda Guerra Mundial. Muchos tomaron pocas o ninguna precaución contra el evento de una exposición, y en un abrir y cerrar de ojos, en un solo destello brillante e indoloro, todo habría terminado para ellos. Días después estaban muertos. Richard Feynman más tarde se refirió a esto como " cosquillas en la cola del dragón"."Así es como puede ser jugar con hilos (al menos para mí de todos modos). Parece bastante inocuo al principio, y cuando te muerden, te rascas la cabeza por la rapidez con la que las cosas se pusieron mal. Pero al menos los hilos ganaron No te mato.

Mike Owens
fuente
Mi respuesta TL; DR palidece en comparación con este buen artículo sobre lo que los hilos individuales no harán por usted.
bmike
1
pausa para el café por la tarde
Mike Owens
10

En primer lugar, una aplicación de un solo subproceso nunca aprovechará una CPU de varios núcleos o un subprocesamiento múltiple. Pero incluso en un solo núcleo, la CPU de un solo subproceso que realiza subprocesos múltiples tiene ventajas.

Considera la alternativa y si eso te hace feliz. Suponga que tiene varias tareas que deben ejecutarse simultáneamente. Por ejemplo, debe seguir comunicándose con dos sistemas diferentes. ¿Cómo se hace esto sin subprocesos múltiples? Probablemente crearía su propio planificador y lo dejaría llamar a las diferentes tareas que deben realizarse. Esto significa que necesita dividir sus tareas en partes. Probablemente necesite cumplir con algunas restricciones en tiempo real, debe asegurarse de que sus piezas no ocupen demasiado tiempo. De lo contrario, el temporizador caducará en otras tareas. Esto hace que dividir una tarea sea más difícil. Cuantas más tareas necesite administrar, más división tendrá que hacer y más complejo será su programador para cumplir con todas las restricciones.

Cuando tienes múltiples hilos, la vida puede ser más fácil. Un planificador preventivo puede detener un subproceso en cualquier momento, mantener su estado y reiniciar (iniciar) otro. Se reiniciará cuando su hilo llegue su turno. Ventajas: la complejidad de escribir un programador ya se ha hecho por usted y no tiene que dividir sus tareas. Además, el planificador es capaz de administrar procesos / subprocesos que usted mismo ni siquiera conoce. Y también, cuando un hilo no necesita hacer nada (está esperando algún evento) no tomará ciclos de CPU. Esto no es tan fácil de lograr cuando está creando su programador de subproceso único. (Dormir algo no es tan difícil, pero ¿cómo se despierta?)

La desventaja del desarrollo de subprocesos múltiples es que debe comprender los problemas de concurrencia, las estrategias de bloqueo, etc. Desarrollar código multiproceso sin errores puede ser bastante difícil. Y la depuración puede ser aún más difícil.

marca
fuente
9

¿Existe algo que solo pueda lograrse mediante el uso de múltiples hilos?

Si. No puede ejecutar código en múltiples CPU o núcleos de CPU con un solo hilo.

Sin múltiples CPU / núcleos, los subprocesos aún pueden simplificar el código que se ejecuta conceptualmente en paralelo, como el manejo del cliente en un servidor, pero podría hacer lo mismo sin subprocesos.

Barro
fuente
6

Los hilos no son solo sobre velocidad sino también sobre concurrencia.

Si no tiene una aplicación por lotes como sugirió @Peter, sino un kit de herramientas GUI como WPF, ¿cómo podría interactuar con los usuarios y la lógica empresarial con solo un hilo?

Además, suponga que está creando un servidor web. ¿Cómo serviría a más de un usuario simultáneamente con un solo hilo (suponiendo que no haya otros procesos)?

Hay muchos escenarios en los que un solo hilo simple no es suficiente. Es por eso que se están produciendo avances recientes como el procesador Intel MIC con más de 50 núcleos y cientos de hilos.

Sí, la programación paralela y concurrente es difícil. Pero necesario.

Randolf Rincón Fadul
fuente
3
"Solo un subproceso" puede significar varias cosas: por ejemplo, puede usar continuaciones delimitadas para simular la multitarea cooperativa dentro de un solo subproceso (SO o verde).
Frank Shearar
Claro, pero estoy dando un pequeño contexto a la pregunta @Frank +1 para el consejo.
Randolf Rincón Fadul
3
Los subprocesos pueden facilitarlo, pero todas las tareas que mencionó se pueden hacer sin subprocesos, y de hecho solían serlo. Por ejemplo, el bucle GUI canónico solía ser while (verdadero) {procesar eventos GUI; calcular un poco}. No se necesitan hilos.
KeithB
Hay servidores web de un solo proceso de un solo subproceso. lighttpd por ejemplo, o thttpd, o nginx (aunque este último puede ejecutar más de un proceso, pero el valor predeterminado es uno. También siempre es de un solo subproceso). No tienen absolutamente ningún problema para atender a más de un usuario.
StasM
6

Multi-Threading puede permitir que la interfaz GUI siga respondiendo durante operaciones de procesamiento prolongadas. Sin subprocesos múltiples, el usuario estaría atrapado viendo un formulario bloqueado mientras se ejecuta un proceso largo.

LarsTech
fuente
Eso no es del todo correcto. En teoría, podría dividir su operación larga en muchas más pequeñas y actualizar el procesamiento de eventos en el medio.
Sebastian Negraszus
@Sebastion N. ¿Pero si el largo proceso no se puede refactorizar en otros más pequeños? La capacidad de ejecutar el proceso en otro subproceso puede liberar el subproceso GUI (el subproceso principal) para que siga respondiendo.
LarsTech
5

El código de subprocesos múltiples puede bloquear la lógica del programa y acceder a datos obsoletos de una manera que los subprocesos individuales no pueden.

Los subprocesos pueden tomar un error oscuro de algo que un programador promedio puede depurar y moverlo al reino donde se cuentan historias de la suerte necesaria para atrapar el mismo error con los pantalones caídos cuando un programador de alerta estaba mirando solo el momento justo.

bmike
fuente
4

las aplicaciones que se ocupan del bloqueo de E / S que también deben permanecer receptivas a otras entradas (la GUI u otras conexiones) no se pueden hacer de una sola hebra

La adición de métodos de verificación en la biblioteca de IO para ver cuánto se puede leer sin bloquear puede ayudar a esto, pero no muchas bibliotecas ofrecen garantías completas sobre esto

monstruo de trinquete
fuente
Pueden ser de un solo subproceso (y a menudo lo fueron). El código le dice al kernel que inicie algunas IO, y recibe una señal cuando se completa. Mientras espera la señal, puede hacer otro procesamiento.
KeithB
@keith eso no -blocking IO dije específicamente bloqueo
trinquete monstruo
Pero, ¿por qué bloquearías IO si quieres seguir respondiendo? ¿Hay alguna IO de bloqueo que generalmente no tenga una alternativa sin bloqueo? No se me ocurre ninguno.
KeithB
El RMI de @keith java está bloqueando y aunque puede implementar una devolución de llamada (pero eso crea otro hilo) con él, pero eso puede ser bloqueado por firewalls
ratchet freak
Eso suena como una limitación de Java RMI, no una limitación inherente del código de subproceso único. Además, si está haciendo RMI, tiene un "hilo" de ejecución separado, solo en una máquina remota.
KeithB
4

Muchas buenas respuestas, pero no estoy seguro de ninguna frase como lo haría, tal vez esto ofrece una forma diferente de verlo:

Los subprocesos son solo una simplificación de programación como Objetos o Actores o para bucles (Sí, cualquier cosa que implemente con bucles puede implementar con if / goto).

Sin hilos simplemente implementas un motor de estado. He tenido que hacer esto muchas veces (la primera vez que lo hice nunca había oído hablar de él, solo hice una gran declaración de cambio controlada por una variable "Estado"). Las máquinas de estado siguen siendo bastante comunes, pero pueden ser molestas. Con hilos, desaparece una gran parte de la caldera.

También hacen que sea más fácil para un lenguaje dividir su ejecución en tiempo de ejecución en fragmentos compatibles con múltiples CPU (también lo hacen los actores, creo).

Java proporciona subprocesos "verdes" en sistemas donde el sistema operativo no proporciona NINGÚN soporte de subprocesos. En este caso, es más fácil ver que claramente no son más que una abstracción de programación.

Bill K
fuente
+1: los subprocesos proporcionan solo una abstracción para el paralelismo en máquinas básicamente secuenciales, al igual que los lenguajes de programación de alto nivel proporcionan una abstracción del código de la máquina.
Mouviciel
0

Los sistemas operativos utilizan el concepto de división de tiempo en el que cada subproceso obtiene su tiempo de ejecución y luego se adelanta. Un enfoque como ese puede reemplazar el subproceso tal como está ahora, pero escribir sus propios programadores en cada aplicación sería excesivo. Además, tendría que trabajar con dispositivos de E / S, etc. Y requeriría un poco de soporte del lado del hardware, para que pueda disparar interrupciones para que su programador se ejecute. Básicamente estarías escribiendo un nuevo sistema operativo cada vez.

En general, el subproceso puede mejorar el rendimiento en los casos en que los subprocesos esperan E / S o están inactivos. También le permite crear interfaces que responden y permite detener procesos, mientras realiza tareas largas. Y también, el enhebrado mejora las cosas en las verdaderas CPU multinúcleo.

Descifrador
fuente
0

Primero, los hilos pueden hacer dos o más cosas al mismo tiempo (si tiene más de un núcleo). Si bien también puede hacer esto con múltiples procesos, algunas tareas simplemente no se distribuyen entre múltiples procesos muy bien.

Además, algunas tareas tienen espacios que no puede evitar fácilmente. Por ejemplo, es difícil leer datos de un archivo en el disco y también hacer que su proceso haga otra cosa al mismo tiempo. Si su tarea requiere necesariamente una gran cantidad de datos de lectura del disco, su proceso pasará mucho tiempo esperando el disco sin importar lo que haga.

En segundo lugar, los subprocesos pueden permitirle evitar tener que optimizar grandes cantidades de su código que no es crítico para el rendimiento. Si solo tiene un hilo único, cada pieza de código es crítica para el rendimiento. Si se bloquea, está hundido: ninguna tarea que se realizaría con ese proceso puede avanzar. Con los subprocesos, un bloque solo afectará a ese subproceso y otros subprocesos pueden aparecer y trabajar en tareas que ese proceso debe realizar.

Un buen ejemplo es el código de manejo de errores ejecutado con poca frecuencia. Digamos que una tarea encuentra un error muy infrecuente y el código para manejar ese error necesita paginarse en la memoria. Si el disco está ocupado y el proceso tiene un solo subproceso, no se puede avanzar hasta que el código para manejar ese error se pueda cargar en la memoria. Esto puede causar una respuesta explosiva.

Otro ejemplo es si rara vez tiene que hacer una búsqueda en la base de datos. Si espera a que la base de datos responda, su código tendrá un gran retraso. Pero no desea tomarse la molestia de hacer que todo este código sea asíncrono porque es muy raro que necesite hacer estas búsquedas. Con un hilo para hacer este trabajo, obtienes lo mejor de ambos mundos. Un hilo para hacer este trabajo hace que no sea crítico para el rendimiento como debería ser.

David Schwartz
fuente