¿Cuál es la diferencia entre un hilo y una fibra?


187

¿Cuál es la diferencia entre un hilo y una fibra? He oído hablar de fibras de rubí y he leído que están disponibles en otros idiomas, ¿podría alguien explicarme en términos simples cuál es la diferencia entre un hilo y una fibra?

Respuestas:


163

En los términos más simples, los hilos generalmente se consideran preventivos (aunque esto no siempre es cierto, dependiendo del sistema operativo), mientras que las fibras se consideran hilos ligeros y cooperativos. Ambas son rutas de ejecución separadas para su aplicación.

Con subprocesos: la ruta de ejecución actual puede interrumpirse o adelantarse en cualquier momento (nota: esta declaración es una generalización y puede no ser cierta según el sistema operativo / paquete de subprocesos / etc.). Esto significa que para los subprocesos, la integridad de los datos es un gran problema porque un subproceso puede detenerse en medio de la actualización de un fragmento de datos, dejando la integridad de los datos en un estado incorrecto o incompleto. Esto también significa que el sistema operativo puede aprovechar múltiples CPU y núcleos de CPU al ejecutar más de un hilo al mismo tiempo y dejar que el desarrollador se encargue del acceso a los datos.

Con fibras: la ruta de ejecución actual solo se interrumpe cuando la fibra produce ejecución (la misma nota que la anterior). Esto significa que las fibras siempre comienzan y se detienen en lugares bien definidos, por lo que la integridad de los datos es un problema mucho menor. Además, debido a que las fibras a menudo se administran en el espacio del usuario, no es necesario realizar costosos cambios de contexto y cambios de estado de la CPU, lo que hace que el cambio de una fibra a la siguiente sea extremadamente eficiente. Por otro lado, dado que no pueden ejecutarse dos fibras exactamente al mismo tiempo, el solo uso de fibras no aprovechará múltiples CPU o múltiples núcleos de CPU.


77
¿Hay alguna forma de usar múltiples hilos para ejecutar fibras en paralelo?
Baradé

2
@ Jason, cuando dice ~ "con fibras, la ruta de ejecución actual solo se interrumpe cuando la fibra produce ejecución" y "las fibras siempre comienzan y se detienen en lugares bien definidos, por lo que la integridad de los datos es mucho menos problemática", ¿quiere decir que al compartir variables, no necesitamos usar "mecanismos de bloqueo" y variables volátiles? ¿O quieres decir que todavía tenemos que hacer esas cosas?
Pacerier

@ Baradé Es una pregunta interesante, ¿encontraste una respuesta?
Mayur

57

Los hilos usan programación preventiva , mientras que las fibras usan programación cooperativa .

Con un subproceso, el flujo de control podría interrumpirse en cualquier momento y otro subproceso puede asumir el control. Con varios procesadores, puede tener varios subprocesos ejecutándose todos al mismo tiempo (subprocesamiento múltiple simultáneo o SMT). Como resultado, debe tener mucho cuidado con el acceso simultáneo a los datos y proteger sus datos con mutexes, semáforos, variables de condición, etc. A menudo es muy difícil hacerlo bien.

Con una fibra, el control solo cambia cuando se lo indica, generalmente con una llamada de función llamada algo así yield(). Esto facilita el acceso simultáneo a los datos, ya que no tiene que preocuparse por la atomicidad de las estructuras de datos o mutexes. Siempre y cuando no ceda, no hay peligro de ser reemplazado y tener otra fibra tratando de leer o modificar los datos con los que está trabajando. Como resultado, sin embargo, si su fibra entra en un bucle infinito, no se puede ejecutar ninguna otra fibra, ya que no está cediendo.

También puede mezclar hilos y fibras, lo que da lugar a los problemas que enfrentan ambos. No se recomienda, pero a veces puede ser lo correcto si se hace con cuidado.


3
Creo que un bucle infinito es solo un error que debe corregirse, y los hilos solo tienen una ventaja bastante oscura cuando hay un bucle infinito. El concepto relacionado sin errores es cuando hay un proceso de larga ejecución que el usuario puede desear cancelar. En este caso, ya sea que use hilos o fibras, el proceso de larga duración debe ser cooperativo: solo matar su hilo puede dejar algunas de sus estructuras de datos en mal estado, por lo que una mejor manera es, por ejemplo, que el hilo del proceso de larga duración verifique periódicamente si hubiera sido interrumpido Esto no es muy diferente de una fibra que produce periódicamente.
Evgeni Sergeev

43

En Win32, una fibra es una especie de subproceso administrado por el usuario. Una fibra tiene su propia pila y su propio puntero de instrucciones, etc., pero las fibras no están programadas por el sistema operativo: debe llamar explícitamente a SwitchToFiber. Los hilos, por el contrario, son programados de manera preventiva por el sistema operativo. En términos generales, una fibra es un subproceso que se administra a nivel de aplicación / tiempo de ejecución en lugar de ser un verdadero subproceso del sistema operativo.

Las consecuencias son que las fibras son más baratas y que la aplicación tiene más control sobre la programación. Esto puede ser importante si la aplicación crea muchas tareas concurrentes y / o quiere optimizar de cerca cuando se ejecutan. Por ejemplo, un servidor de base de datos podría optar por utilizar fibras en lugar de hilos.

(Puede haber otros usos para el mismo término; como se señaló, esta es la definición de Win32).


37

Primero, recomendaría leer esta explicación de la diferencia entre procesos y subprocesos como material de fondo.

Una vez que hayas leído eso, es bastante sencillo. Los subprocesos se pueden implementar en el núcleo, en el espacio del usuario, o los dos se pueden mezclar. Las fibras son básicamente hilos implementados en el espacio del usuario.

  • Lo que generalmente se llama un hilo es un hilo de ejecución implementado en el núcleo: lo que se conoce como un hilo del núcleo. La programación de un hilo del kernel es manejada exclusivamente por el kernel, aunque un hilo del kernel puede liberar voluntariamente la CPU durmiendo si lo desea. Un subproceso del núcleo tiene la ventaja de que puede usar el bloqueo de E / S y dejar que el núcleo se preocupe por la programación. Su principal desventaja es que el cambio de subprocesos es relativamente lento, ya que requiere quedar atrapado en el núcleo.
  • Las fibras son hilos de espacio de usuario cuya programación es manejada en el espacio de usuario por uno o más hilos de kernel en un solo proceso. Esto hace que el cambio de fibra sea muy rápido. Si agrupa todas las fibras que acceden a un conjunto particular de datos compartidos en el contexto de un solo hilo del núcleo y su programación se maneja por un solo hilo del núcleo, entonces puede eliminar los problemas de sincronización ya que las fibras se ejecutarán efectivamente en serie y habrá completado control sobre su programación. La agrupación de fibras relacionadas bajo un solo hilo del núcleo es importante, ya que el hilo del núcleo en el que se están ejecutando puede ser adelantado por el núcleo. Este punto no se aclara en muchas de las otras respuestas. Además, si utiliza el bloqueo de E / S en una fibra, todo el hilo del núcleo forma parte de los bloques, incluidas todas las fibras que forman parte de ese hilo del núcleo.

En la sección 11.4 "Procesos y subprocesos en Windows Vista" en sistemas operativos modernos, Tanenbaum comenta:

Aunque las fibras se programan de manera cooperativa, si hay múltiples hilos que programan las fibras, se requiere una sincronización cuidadosa para asegurarse de que las fibras no interfieran entre sí. Para simplificar la interacción entre hilos y fibras, a menudo es útil crear solo tantos hilos como procesadores para ejecutarlos, y afinar los hilos a cada ejecución solo en un conjunto distinto de procesadores disponibles, o incluso en un solo procesador. Cada hilo puede ejecutar un subconjunto particular de fibras, estableciendo una relación uno a muchos entre hilos y fibras que simplifica la sincronización. Aun así, todavía hay muchas dificultades con las fibras. La mayoría de las bibliotecas Win32 desconocen por completo las fibras, y las aplicaciones que intentan usar fibras como si fueran hilos encontrarán varios fallos. El núcleo no tiene conocimiento de las fibras, y cuando una fibra ingresa al núcleo, el hilo en el que se está ejecutando puede bloquearse y el núcleo programará un hilo arbitrario en el procesador, por lo que no estará disponible para ejecutar otras fibras. Por estas razones, las fibras rara vez se usan, excepto cuando se transfiere código de otros sistemas que necesitan explícitamente la funcionalidad proporcionada por las fibras.


44
Esta es la respuesta más completa.
Bernard

12

Tenga en cuenta que, además de hilos y fibras, Windows 7 presenta la programación en modo de usuario :

La programación en modo de usuario (UMS) es un mecanismo ligero que las aplicaciones pueden usar para programar sus propios subprocesos. Una aplicación puede cambiar entre subprocesos UMS en modo de usuario sin involucrar al programador del sistema y recuperar el control del procesador si un subproceso UMS se bloquea en el núcleo. Los subprocesos UMS difieren de las fibras en que cada subproceso UMS tiene su propio contexto de subproceso en lugar de compartir el contexto del subproceso de un solo subproceso. La capacidad de cambiar entre hilos en modo de usuario hace que UMS sea más eficiente que los grupos de hilos para administrar grandes cantidades de elementos de trabajo de corta duración que requieren pocas llamadas al sistema.

Para obtener más información sobre hilos, fibras y UMS, consulte Dave Probert: Inside Windows 7 - User Mode Scheduler (UMS) .


7

Los subprocesos son programados por el sistema operativo (preventivo). El sistema operativo puede detener o reanudar un subproceso en cualquier momento, pero las fibras se manejan más o menos por sí mismas (cooperativas) y ceden entre sí. Es decir, el programador controla cuándo las fibras realizan su procesamiento y cuándo ese procesamiento cambia a otra fibra.


7

Los subprocesos generalmente dependen del núcleo para interrumpir el subproceso para que este u otro subproceso pueda ejecutarse (lo que se conoce mejor como multitarea preventiva), mientras que las fibras usan multitarea cooperativa donde es la fibra misma la que abandona su tiempo de ejecución para que otras fibras pueden correr.

Algunos enlaces útiles que lo explican mejor de lo que probablemente hice son:


7

Los hilos fueron creados originalmente como procesos ligeros. De manera similar, las fibras son un hilo liviano, que se basa (de manera simplista) en las fibras para programarse entre sí, al ceder el control.

Supongo que el siguiente paso serán los hilos donde tendrás que enviarles una señal cada vez que quieras que ejecuten una instrucción (no muy diferente de mi hijo de 5 años :-). En los viejos tiempos (e incluso ahora en algunas plataformas integradas), todos los subprocesos eran fibras, no había preferencia y tenía que escribir sus subprocesos para comportarse bien.


3

La definición de fibra Win32 es, de hecho, la definición de "hilo verde" establecida en Sun Microsystems. No hay necesidad de desperdiciar el término fibra en el hilo de algún tipo, es decir, un hilo que se ejecuta en el espacio de usuario bajo el código de usuario / control de biblioteca de hilos.

Para aclarar el argumento, mire los siguientes comentarios:

  • Con Hyper-Threading, la CPU multi-core puede aceptar múltiples hilos y distribuirlos en cada núcleo.
  • La CPU canalizada superescalar acepta un subproceso para su ejecución y utiliza el paralelismo de nivel de instrucción (ILP) para ejecutar el subproceso más rápido. Podemos suponer que un hilo se divide en fibras paralelas que se ejecutan en tuberías paralelas.
  • La CPU SMT puede aceptar múltiples subprocesos y frenarlos en fibras de instrucciones para ejecución paralela en múltiples tuberías, utilizando tuberías de manera más eficiente.

Debemos suponer que los procesos están hechos de hilos y que los hilos deben estar hechos de fibras. Con esa lógica en mente, usar fibras para otro tipo de hilos está mal.


Esto es interesante.
JSON
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.