Python/Erlang: ¿Cuál es la diferencia entre Twisted, Stackless, Greenlet, Eventlet, Coroutines? ¿Son similares a los procesos de Erlang?
asynchronous nonblocking (3)
Mi entendimiento incompleto es que Twisted, Stackless, Greenlet, Eventlet, Coroutines hacen uso de async network IO y de los hilos de userland que son muy livianos y rápidos de cambiar. Pero no estoy seguro de cuáles son las diferencias entre ellos.
También suenan muy similares a los procesos de Erlang. ¿Son más o menos lo mismo?
Cualquiera que pueda ayudarme a entender este tema más será muy apreciado.
¡Cebo tomado! (arreglos bienvenidos!):
Gravemente:
- retorcido: rosca simple. logra un comportamiento no bloqueante a través del uso de modismos ''de devolución de llamada'' y ''diferidos''. Similar a node.js.
- greenlet / eventlet: use ''hilos verdes'' (¿secciones de memoria?) para lograr io no bloqueante. En realidad, parchea el CPython IO estándar con sus versiones, por lo que el código se escribe como si fuera bloqueante / secuencial.
- sin pilas: Stackless . ¿No lo has usado, parece que agrega ''microthreads'' y otras sutilezas? sin apilar modismos idiomáticos
- corutinas: corutinas en SO
Ninguno de estos son tan ligeros ni están bien respaldados como los procesos de Erlang.
En primer lugar, la E / S sin bloqueo no tiene nada en común con los hilos verdes o coroutines, pero puede afectar la forma en que están programados.
Ahora:
- Twisted es un marco clásico de E / S sin bloqueo: el código de la aplicación está escrito en estilo asíncrono mediante devoluciones de llamada.
- Gevent y eventlet usan la biblioteca de greenlet para corutinas / greenthreads / greenlets. Hay un greenlet dedicado para ejecutar el evento (en el caso de gevent es un ciclo de evento de libevent codificado). Cuando greenlet arbitrario comienza a esperar a que se procese alguna operación de E / S, simplemente ejecuta el bucle de evento, que inicia otro greenlet para su ejecución (que está listo para hacer E / S). Esto se llama multitarea cooperativa: cada greenlet decide cuándo devolver el control a otros greenlets.
- Stackless tiene tasklets, que son similares a greenlets, pero también se pueden programar con un modelo preventivo, lo que significa que el planificador puede detener la ejecución del tasklet en cualquier momento y comenzar la ejecución de otra tasklet (que es cómo funcionan los subprocesos del sistema operativo y Erlang). Además, Stackless no proporciona ninguna instalación de E / S sin bloqueo, por lo que si realiza E / S a través de stdlib, bloqueará toda la secuencia del sistema operativo, de modo que no se podrá ejecutar ninguna otra tarea mientras espera en I / O. Hubo intentos de proporcionar un puerto de la biblioteca gevent para Stackless, pero no sé cómo va.
Estás casi en lo cierto al comparar Stackless con Greenlet. Lo que falta es:
Stackless per se no agrega algo. En cambio, Greenlet, inventado 5 años después de Stackless, elimina ciertas cosas. Está escrito lo suficientemente simple para ser construido como un módulo de extensión en lugar de un intérprete de reemplazo.
Esto es realmente divertido: Stackless tiene muchas más características, es aproximadamente 10 veces más eficiente en la conmutación y proporciona un estado de decapado del estado de ejecución.
Greenlet aún gana, probablemente solo debido a la facilidad de uso como módulo de extensión. Así que estoy pensando en revertir el proceso extendiendo Greenlet con decapado. Tal vez eso cambiaría la imagen, de nuevo :-)