Pregunta

No tengo sin pila ejecutándose actualmente, así que no puedo probarlo yo mismo.

import stackless
ch1 = stackless.channel()
ch2 = stackless.channel()

ch1.send(ch2)
ch3 = ch1.receive()

¿Son ch2 y ch3 el mismo canal? Diga:

text = "Hallo"
ch2.send(text)
assert text == ch3.receive()

Esta función me recordó una habla sobre Newsqueak que Robert Pike (de < a href = "http://en.wikipedia.org/wiki/Plan_9_from_Bell_Labs" rel = "nofollow noreferrer"> Plan9 fama) dio en Google. En Newsqueak puede enviar canales a través de canales.

¿Fue útil?

Solución

Sí Acabo de probar.

>>> import stackless
>>> ch1 = stackless.channel()
>>> def a():
...  ch2 = stackless.channel()
...  ch1.send(ch2)
...  ch2.send("Hello")
...
>>> def b():
...  ch3 = ch1.receive()
...  print ch3.receive()
...
>>> stackless.tasklet(a)()
<stackless.tasklet object at 0x01C6FCB0>
>>> stackless.tasklet(b)()
<stackless.tasklet object at 0x01C6FAB0>
>>> stackless.run()
Hello

Otros consejos

Los canales envían referencias normales de Python, por lo que los datos que envía (canal, cadena, lo que sea) es exactamente lo que se recibe.

Un ejemplo de envío de un canal a través de un canal es cuando utiliza un tasklet como servicio, es decir, un tasklet escucha solicitudes en un canal, funciona y devuelve el resultado. La solicitud debe incluir los datos para el trabajo y el canal de retorno para el resultado, de modo que el resultado llegue al solicitante.

Aquí hay un ejemplo extremo que desarrollé para mi Charla sin pila en PyCon hace unos años. Esto crea un nuevo tasklet para cada llamada de función, por lo que puedo usar una implementación recursiva de factorial que no necesita preocuparse por el límite de pila de Python. Asigno un tasklet para cada llamada y obtiene el canal de retorno para el resultado.

import stackless 

def call_wrapper(f, args, kwargs, result_ch): 
    result_ch.send(f(*args, **kwargs)) 
    # ... should also catch and forward exceptions ... 

def call(f, *args, **kwargs): 
    result_ch = stackless.channel() 
    stackless.tasklet(call_wrapper)(f, args, kwargs, result_ch) 
    return result_ch.receive() 

def factorial(n): 
    if n <= 1: 
        return 1 
    return n * call(factorial, n-1) 

print "5! =", factorial(5) 
print "1000! / 998! =", factorial(1000)/factorial(998)

El resultado es:

5! = 120 
1000! / 998! = 999000

Tengo algunos otros ejemplos de envío de canales a través de canales en mi presentación. Es algo común en Stackless.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top