4

私は現在スタックレスを実行していないので、これを自分で試すことはできません。

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

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

ch2ch3は同じチャンネルですか?言う:

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

この機能を見て、Robert Pike (Plan9 で有名) が Google で行ったNewsqueakに関する講演を思い出しました。Newsqueak では、チャネルを介してチャネルを送信できました。

4

2 に答える 2

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
于 2009-03-12T14:26:27.217 に答える
3

チャネルは通常の Python 参照を送信するため、送信するデータ (チャネル、文字列など) は正確に受信されます。

チャネルを介してチャネルを送信する 1 つの例は、タスクレットをサービスとして使用する場合です。つまり、タスクレットはチャネルで要求をリッスンし、動作し、結果を返します。リクエストには、結果がリクエスタに送られるように、作業のデータと結果のリターン チャネルを含める必要があります。

これは、数年前のPyCon での Stackless の講演のために開発した極端な例です。これにより、関数呼び出しごとに新しいタスクレットが作成されるため、Python のスタック制限を気にする必要のない再帰的な factorial の実装を使用できます。呼び出しごとにタスクレットを割り当て、結果のリターン チャネルを取得します。

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

私のプレゼンテーションでは、チャネルを介してチャネルを送信する例を他にもいくつか紹介しています。スタックレスではよくあることです。

于 2009-03-12T17:05:14.047 に答える