2009-04-28 29 views

Respuesta

120

En los términos más simples, los hilos generalmente se consideran preventivos (aunque esto puede no ser siempre 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 afirmación es una generalización y puede no ser siempre cierta dependiendo de OS/threading package/etc.). Esto significa que para los hilos, la integridad de los datos es un gran problema porque un hilo se puede detener en el medio de actualizar una porción de datos, dejando la integridad de los datos en un estado malo o incompleto. Esto también significa que el sistema operativo puede aprovechar múltiples CPU y núcleos de CPU ejecutando más de un hilo al mismo tiempo y dejándolo al desarrollador para proteger el acceso a los datos.

Con fibras: la ruta de ejecución actual solo se interrumpe cuando la fibra produce la ejecución (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 mucho menos problemática. Además, como las fibras a menudo se gestionan en el espacio del usuario, no es necesario realizar costosos cambios de contexto ni cambios en el estado de la CPU, lo que hace que el cambio de una fibra a otra sea extremadamente eficiente. Por otro lado, dado que no se pueden ejecutar dos fibras exactamente al mismo tiempo, el solo uso de fibras por sí solo no aprovechará múltiples CPU o múltiples núcleos de CPU.

+5

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

+1

@Jason, cuando declaras ~ "con fibras, la ruta de ejecución actual solo se interrumpe cuando la fibra produce la 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", ¿te refieres? que al compartir variables, no necesitamos usar "mecanismos de bloqueo" y variables volátiles? ¿O quiere decir que todavía tenemos que hacer esas cosas? – Pacerier

42

En Win32, una fibra es una especie de subproceso administrado por el usuario. Una fibra tiene su propia pila y su propio puntero de instrucción, etc., pero el sistema operativo no programa las fibras: debe llamar a SwitchToFiber explícitamente. Los subprocesos, por el contrario, son programados de manera preventiva por el sistema operativo. En términos generales, una fibra es un hilo que se gestiona en el nivel de aplicación/tiempo de ejecución en lugar de ser una verdadera hebra 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 simultáneas y/o desea optimizar de cerca cuando se ejecutan. Por ejemplo, un servidor de base de datos puede elegir usar fibras en lugar de hilos.

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

7

Hilos están programados por el sistema operativo (preventiva). El sistema operativo puede detener o reanudar un hilo en cualquier momento, pero las fibras se administran más o menos (cooperativas) y ceden el uno al otro. Es decir, el programador controla cuando las fibras hacen su procesamiento y cuando ese procesamiento cambia a otra fibra.

5

En general, los hilos dependen del núcleo para interrumpir el hilo para que se pueda ejecutar u otro hilo (que es mejor conocido como multitarea preventiva) mientras que las fibras usan multitarea cooperativa donde es la fibra misma la que renuncia a su tiempo de funcionamiento para que otras fibras puedan funcionar.

Algunos enlaces útiles que explican mejor que yo probablemente lo hizo son:

42

Hilos utilizan preventiva programación, mientras que las fibras utilizan cooperativa scheduli ng.

Con un hilo, el flujo de control podría interrumpirse en cualquier momento, y otro hilo puede hacerse cargo. Con múltiples procesadores, puede tener múltiples hilos ejecutándose todos al mismo tiempo (simultáneo multihilo, o SMT). Como resultado, debe ser muy teniendo cuidado con el acceso concurrente a los datos y proteger sus datos con mutexes, semáforos, variables de condición, etc. A menudo es muy complicado acertar.

Con una fibra, el control solo cambia cuando se lo indica, generalmente con una llamada a función llamada algo así como 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 los mensajes muteos. Mientras no ceda, no hay peligro de ser adelantado y tener otra fibra tratando de leer o modificar los datos con los que está trabajando. Como resultado, sin embargo, si la fibra entra en un ciclo infinito, no se puede ejecutar ninguna otra fibra, ya que no cede.

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.

+2

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 que no tiene errores es cuando hay un proceso de larga ejecución que el usuario puede querer cancelar. En este caso, ya sea que use hilos o fibras, el proceso de larga duración debe ser cooperativo: simplemente matar su hilo podría dejar algunas de sus estructuras de datos en mal estado, por lo que una mejor forma es, por ejemplo, el hilo de proceso de larga ejecución verificaría periódicamente si se hubiera interrumpido. Esto no es tan diferente de una fibra que rinde periódicamente. –

6

Los hilos se crearon originalmente como procesos livianos. De manera similar, las fibras son un hilo ligero, que confía (de forma simplista) en las fibras mismas para programarse entre sí, al ceder el control.

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

12

Nota que, además de hilos y fibras, Windows 7 introduce User-Mode Scheduling:

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

Más información sobre hilos, fibras y UMS está disponible al mirar Dave Probert: Inside Windows 7 - User Mode Scheduler (UMS).

30

Primero, recomendaría leer esta explicación de the difference between processes and threads como material de fondo.

Una vez que haya leído que es bastante sencillo. Los hilos se pueden implementar en el kernel, en el espacio de usuario, o los dos se pueden mezclar. Las fibras son básicamente hilos implementados en el espacio del usuario.

  • Lo que se suele llamar un hilo es un hilo de ejecución implementado en el kernel: lo que se conoce como 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 el CPU durmiendo si lo desea. Un hilo del núcleo tiene la ventaja de que puede usar E/S de bloqueo y le permite al núcleo preocuparse por la programación. Su principal desventaja es que la conmutación de subprocesos es relativamente lenta, ya que requiere atrapamiento en el kernel.
  • Las fibras son subprocesos de espacio de usuario cuya programación se maneja en el espacio de usuario por uno o más subprocesos del núcleo en un único proceso. Esto hace que la conmutación de fibra sea muy rápida. Si agrupa todas las fibras que acceden a un conjunto particular de datos compartidos en el contexto de una única hebra del kernel y su programación se maneja con una sola hebra del kernel, 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. Agrupar las fibras relacionadas bajo un único hilo de kernel es importante, ya que el núcleo puede anticipar el hilo del kernel en el que se están ejecutando. Este punto no está claro en muchas de las otras respuestas. Además, si usa E/S de bloqueo en una fibra, todo el hilo del kernel es una parte de los bloques, incluidas todas las fibras que forman parte de esa cadena del kernel.

En la sección 11.4 "los procesos y subprocesos en Windows Vista" en los sistemas operativos modernos, los comentarios Tanenbaum:

Aunque las fibras están cooperativamente programadas, si hay varios hilos de la programación de las fibras, una gran cantidad de se requiere una sincronización cuidadosa para asegurarse de que las fibras no interfieran entre sí. Para simplificar la interacción entre subprocesos y fibras, a menudo es útil para crear solo tantos subprocesos como procesadores para ejecutarlos y afinizar los subprocesos para cada ejecución solo en un conjunto distinto de procesadores disponibles, o incluso solo un procesador Cada hilo puede luego ejecutar un subconjunto particular de las fibras, estableciendo una relación to-many 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 utilizar las fibras como si fueran hilos van a encontrar varios fallos. El núcleo no tiene conocimiento de las fibras, y cuando una fibra ingresa al kernel, el hilo 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. Para estas razones , las fibras se usan raramente, excepto cuando se transfiere el código de otros sistemas que requieren explícitamente la funcionalidad provista por las fibras.

+3

Esta es la respuesta más completa. – Alkaline

1

Definición de fibra Win32 es, de hecho, la definición de "Green Thread" establecida en Sun Microsystems. No es necesario perder el término fibra en el hilo de algún tipo, es decir, un subproceso que se ejecuta en el espacio de usuario bajo el código de usuario/control de biblioteca de subprocesos.

Para aclarar el aspecto discusión en los siguientes comentarios:

  • con Hyper-threading, multi-core CPU puede aceptar múltiples hilos y distribuirlos uno en cada núcleo.
  • Supertecalar pipeline CPU acepta un subproceso para 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 rompe en fibras paralelas que corren en tuberías paralelas.
  • La CPU SMT puede aceptar múltiples hilos y frenarlos en fibras de instrucciones para la ejecución en paralelo de en múltiples tuberías, utilizando tuberías de manera más eficiente.

Deberíamos asumir 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 otros tipos de hilos es incorrecto.

0

A La fibra es un hilo ligero que utiliza la multitarea cooperativa en lugar de la multitarea preventiva. Una fibra en ejecución debe "ceder" explícitamente para permitir que se ejecute otra fibra, lo que hace que su implementación sea mucho más fácil que los hilos del kernel o del usuario.

A Coroutine es un componente que generaliza una subrutina para permitir puntos de entrada múltiples para suspender y reanudar la ejecución en ciertas ubicaciones. A diferencia de las subrutinas, las corutinas pueden salir llamando a otras corutinas, que luego pueden volver al punto en el que se invocaron en la corutina original.

Cuestiones relacionadas