Pergunta

eu não tenho sem pilha Atualmente em execução, então não posso tentar isso sozinho.

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

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

São CH2 e CH3 então o mesmo canal? Dizer:

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

Esse recurso me lembrou de um Fale sobre o Newsqueak que Robert Pike (de Plan9 fama) deu no Google. No Newsqueak, você pode enviar canais sobre canais.

Foi útil?

Solução

Sim. Acabei de testar.

>>> 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

Outras dicas

Os canais enviam referências normais do Python para que os dados que você envie (canal, string, o que seja) é exatamente o que é recebido.

Um exemplo de envio de um canal sobre um canal é quando você usa um Tasklet como um serviço, ou seja, um TaskLet ouve um canal para solicitações, funciona e retorna o resultado. A solicitação precisa incluir os dados para o trabalho e o canal de retorno para o resultado, para que o resultado vá para o solicitante.

Aqui está um exemplo extremo que desenvolvi para o meu Conversa sem pilha em pycon alguns anos atrás. Isso cria um novo Tasklet para cada chamada de função para que eu possa usar uma implementação recursiva do fatorial que não precisa se preocupar com o limite de pilha do Python. Eu alquei um Tasklet para cada chamada e ele recebe o canal de retorno para o 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)

A saída é:

5! = 120 
1000! / 998! = 999000

Tenho alguns outros exemplos de envio de canais sobre canais em minha apresentação. É uma coisa comum na pilha.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top