スタックレスPythonでは、チャネルを介してチャネルを送信できますか?
-
10-07-2019 - |
質問
現在、スタックレスを実行していないため、自分でこれを試すことはできません。
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()
この機能は、ロバートパイク(< href = "http://en.wikipedia.org/wiki/Plan_9_from_Bell_Labs" rel = "nofollow noreferrer"> Plan9 の名声)がGoogleで与えられました。 Newsqueakでは、チャンネルを介してチャンネルを送信できます。
解決
はい。テスト済み。
>>> 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
他のヒント
チャネルは通常のPython参照を送信するため、送信するデータ(チャネル、文字列など)は正確に受信されます。
チャンネルを介してチャンネルを送信する1つの例は、タスクレットをサービスとして使用する場合です。つまり、タスクレットはチャンネルでリクエストをリッスンし、動作し、結果を返します。リクエストには、結果がリクエスターに送られるように、作業のデータと結果のリターンチャネルを含める必要があります。
これは、数年前に PyConでのスタックレストークのために開発した極端な例です。これにより、関数呼び出しごとに新しいタスクレットが作成されるため、Pythonのスタック制限を心配する必要のない、階乗の再帰的な実装を使用できます。各呼び出しにタスクレットを割り当て、結果のリターンチャネルを取得します。
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ではよくあることです。
所属していません StackOverflow