python python-stackless

¿Para qué usaría Stackless Python?



python-stackless (6)

Hay muchas preguntas relacionadas con Stackless Python. Pero ninguno responde a mi pregunta, creo (corríjame si me equivoco, ¡por favor!). Hay algo de revuelo al respecto todo el tiempo, así que tengo curiosidad por saberlo. ¿Para qué usaría Stackless? ¿Cómo es mejor que CPython?

Sí, tiene hilos verdes (sin apilamiento) que permiten crear rápidamente muchos hilos ligeros siempre que no haya operaciones bloqueadas (¿algo así como los hilos de Ruby?). ¿Para qué sirve esto? ¿Qué otras funciones tengo que usar sobre CPython?


EVEOnline está en gran parte programado en Python sin pila. Tienen varios blogs de desarrollo sobre el uso de la misma. Parece que es muy útil para computación de alto rendimiento.


El principal beneficio de Stackless Python es el soporte para coroutinas muy ligeras. CPython no admite coroutines de forma nativa (aunque espero que alguien publique un hack basado en un generador en los comentarios), por lo que Stackless es una clara mejora en CPython cuando tiene un problema que se beneficia de coroutines.

Creo que el área principal donde sobresalen es cuando tiene muchas tareas simultáneas ejecutándose dentro de su programa. Los ejemplos pueden ser entidades de juego que ejecutan un script de bucle para su AI, o un servidor web que atiende a muchos clientes con páginas que tardan en crearse.

Sin embargo, aún tiene muchos de los problemas típicos con la corrección de la concurrencia con respecto a los datos compartidos, pero el cambio de tarea determinista facilita la escritura de código seguro, ya que sabe exactamente dónde se transferirá el control y, por lo tanto, conoce los puntos exactos en los que debe estar el estado compartido. A hoy.


La utilidad básica de los hilos verdes, tal como lo veo, es implementar un sistema en el que tengas una gran cantidad de objetos que realicen operaciones de alta latencia. Un ejemplo concreto sería la comunicación con otras máquinas:

def Run(): # Do stuff request_information() # This call might block # Proceed doing more stuff

Los subprocesos le permiten escribir el código anterior de forma natural, pero si el número de objetos es lo suficientemente grande, los subprocesos simplemente no pueden funcionar adecuadamente. Pero puedes usar hilos verdes incluso en cantidades realmente grandes. La request_information() anterior podría cambiar a un programador donde otro trabajo está esperando y volver más tarde. Obtiene todos los beneficios de poder llamar a las funciones de "bloqueo" como si regresaran inmediatamente sin usar subprocesos.

Obviamente, esto es muy útil para cualquier tipo de computación distribuida si desea escribir código de una manera directa.

También es interesante para múltiples núcleos mitigar los bloqueos en espera:

def Run(): # Do some calculations green_lock(the_foo) # Do some more calculations

La función green_lock básicamente intentaría adquirir el bloqueo y simplemente cambiar a un programador principal si falla debido a otros núcleos que usan el objeto.

Nuevamente, los hilos verdes se están utilizando para mitigar el bloqueo, lo que permite que el código se escriba de forma natural y siga funcionando bien.


Si bien no he usado el mismo Stackless, he usado Greenlet para implementar aplicaciones de red altamente concurrentes. Algunos de los casos de uso que Linden Lab ha presentado son: proxies inteligentes de alto rendimiento, un sistema rápido para distribuir comandos en un gran número de máquinas, y una aplicación que hace una tonelada de bases de datos de escritura y lectura (en una proporción de aproximadamente 1 : 2, que es muy pesado en escritura, por lo que pasa la mayor parte del tiempo esperando a que regrese la base de datos), y una cosa de tipo rastreador web para datos web internos. Básicamente, cualquier aplicación que espere tener que hacer una gran cantidad de E / S de red se beneficiará de ser capaz de crear una cantidad de subprocesos livianos de menos de un billón. 10,000 clientes conectados no me parecen un gran problema.

Aunque Stackless o Greenlet no son realmente una solución completa. Son de muy bajo nivel y vas a tener que hacer muchos trabajos de simulación para crear una aplicación con ellos que los utilice al máximo. Lo sé porque mantengo una biblioteca que proporciona una capa de red y programación sobre Greenlet, específicamente porque escribir aplicaciones es mucho más fácil con eso. Hay un montón de estos ahora; Mantengo Eventlet, pero también hay Concurrence, Chiral, y probablemente algunos más que no conozco.

Si el tipo de aplicación que desea escribir suena como lo que escribí, considere una de estas bibliotecas. La elección de Stackless vs Greenlet es algo menos importante que decidir qué biblioteca se adapta mejor a las necesidades de lo que quiere hacer.


Te permite trabajar con grandes cantidades de concurrencia. Nadie en su sano juicio podría crear cien mil hilos de sistema, pero puede hacerlo usando stackless.

Este artículo prueba hacer exactamente eso, creando cien mil tasklets tanto en Python como en Google Go (un nuevo lenguaje de programación): http://dalkescientific.com/writings/diary/archive/2009/11/15/100000_tasklets.html

Sorprendentemente, incluso si Google Go está compilado a código nativo, y promocionan la implementación de sus co-rutinas, Python aún gana.

Stackless sería bueno para implementar un algoritmo de mapa / reducción, donde puede tener un gran número de reductores dependiendo de los datos de entrada.


Thirler ya mencionó que se utilizó stackless en Eve Online. Manten eso en mente:

(..) stackless agrega un giro adicional a esto al permitir que las tareas se separen en tareas más pequeñas, Tasklets, que luego se pueden separar del programa principal para que se ejecuten por su cuenta. Esto se puede usar para tareas de fuego y olvido, como enviar un correo electrónico, enviar un evento o para operaciones de E / S, por ejemplo, enviar y recibir paquetes de red. Un tasklet espera un paquete de la red mientras que otros continúan ejecutando el bucle del juego.

De alguna manera es como los hilos, pero no es preventivo y está programado explícitamente, por lo que hay menos problemas con la sincronización. Además, el cambio entre tasklets es mucho más rápido que el cambio de subprocesos, y puede tener una gran cantidad de tasklets activos mientras que el número de subprocesos está muy limitado por el hardware de la computadora.

(obtuve esta cita de here )

En PyCon 2009 se dio una charla muy interesante , describiendo por qué y cómo se usa Stackless en los Juegos CCP.

Además, hay un muy buen material de introducción que describe por qué stackless es una buena solución para Sus aplicaciones. (Puede ser algo viejo, pero creo que vale la pena leerlo).