2009-03-12 4 views
4

스택이없는이 현재 실행 중이므로 직접 시도 할 수 없습니다.스택이없는 파이썬에서 채널을 통해 채널을 보낼 수 있습니까?

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

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

CH2 다음 CH3 동일한 채널 있습니까? 말 :

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

이 기능은 (Plan9 명예의) 로버트 파이크는 구글 준 talk about Newsqueak를 생각 나게했다. Newsqueak에서는 채널을 통해 채널을 보낼 수 있습니다.

+0

재밌 네요. Stackless에 대해 정확히 생각하고 있었고 Go/Newsqueak과 같은 채널을 가지고있는 것을 좋아합니다. – Jyaan

답변

4

예. 방금 테스트되었습니다.

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

채널은 정상적인 Python 참조를 전송하므로 사용자가 보내는 데이터 (채널, 문자열 등)는 정확히 수신됩니다.

채널을 통해 채널을 전송하는 한 가지 예는 태스크 릿을 서비스로 사용하는 경우입니다. 즉, 태스크 릿릿은 요청에 대한 채널을 수신하고 작동하고 결과를 반환합니다. 요청에는 작업 데이터와 결과에 대한 반환 채널이 포함되어야 결과가 요청자에게 전달됩니다.

몇 년 전 나의 Stackless talk at PyCon에 대해 개발 한 극단적 인 예입니다. 이것은 각 함수 호출을위한 새로운 태스크 릿을 생성하므로 파이썬의 스택 한계에 대해 걱정할 필요가없는 계승의 재귀 적 구현을 ​​사용할 수 있습니다. 나는 각 호출에 대해 tasklet을 할당하고 결과에 대한 리턴 채널을 얻는다.

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) 

출력은 다음과 같습니다

5! = 120 
1000!/998! = 999000 

나는 나의 프리젠 테이션에 채널을 통해 채널을 전송하는 몇 가지 다른 사례가있다. Stackless에서는 공통점이 있습니다.

관련 문제