hi, 最近看了关于Python协程的相关文章协程的简单理解,说协程可以无限递归,于是想写一个协程示例练练,于是:
import time
def ping():
print 'ping 0'
count = 1
try:
pi,po = yield s
print 'ping ' + str(count)
count += 1
time.sleep(1)
po.send([po, pi])
except StopIteration:
pass
def pong():
print 'pong 0'
count = 1
try:
po, pi = yield s
print 'pong ' + str(count)
count += 1
time.sleep(1)
pi.send([pi,po])
except StopIteration:
pass
s = ping()
r = pong()
s.next()
r.next()
s.send([s,r])
运行结果是:
ping 0
pong 0
ping 1
pong 1
Traceback (most recent call last):
File "D:\test\coroutine.py", line 34, in <module>
s.send([s,r])
File "D:\test\coroutine.py", line 12, in ping
po.send([po, pi])
File "D:\test\coroutine.py", line 25, in pong
pi.send([pi,po])
ValueError: generator already executing
那篇文章使用了stackless,我想实现一个原始的方法。但是出错,不知道要实现无限递归的话,应该怎么写嘞?
天蓬老师2017-04-17 15:46:45
What you need is to use a run function to manage the coroutine.
In the ping and pong functions, yield returns run.
In the run function, use next() to schedule the coroutine.
import time
def ping():
print 'ping 0'
count = 1
while 1:
yield po
print 'ping ' + str(count)
count += 1
time.sleep(1)
def pong():
print 'pong 0'
count = 1
while 1:
yield pi
print 'pong ' + str(count)
count += 1
time.sleep(1)
def run(co):
while 1:
co = co.next() # 这行实现 ping 和 pong 交替运行
pi = ping()
po = pong()
pi.next()
po.next()
run(pi)
Run result:
ping 0
pong 0
ping 1
pong 1
ping 2
pong 2
ping 3
pong 3
ping 4
pong 4
......
==================================================== =======
With messaging version:
import time
def ping():
print 'ping 0'
count = 1
while 1:
msg = yield (po, 'msg from ping')
print 'ping get', msg
print 'ping ' + str(count)
count += 1
time.sleep(1)
def pong():
print 'pong 0'
count = 1
while 1:
msg = yield (pi, 'msg from pong')
print 'pong get', msg
print 'pong ' + str(count)
count += 1
time.sleep(1)
def run(cur, msg='msg from run'):
while 1:
cur, msg = cur.send(msg)
pi = ping()
po = pong()
pi.next()
po.next()
run(pi)
Run result:
ping 0
pong 0
ping get msg from run
ping 1
pong get msg from ping
pong 1
ping get msg from pong
ping 2
pong get msg from ping
pong 2
getping msg from pong
ping 3
pong get msg from ping
pong 3
ping get msg from pong
ping 4
............
PHP中文网2017-04-17 15:46:45
There is indeed a problem with what you wrote, but the most important thing is that Stackless is a modified version of Python. Its coroutines seem to be different from those in standard CPython. If you want to implement similar functions in CPython, you may need to Based on greenlet.
高洛峰2017-04-17 15:46:45
http://anandology.com/blog/using-iterators-and-generators/
It should be that the problem is caused by passing the generator itself, and it is caused by send itself
If pi po is a global variable, there should be no problem
迷茫2017-04-17 15:46:45
The usage of the generator is obviously wrong. s is not suspended by yield. Of course, if you go to send/next again, this error will be reported
I don’t know what you want to achieve specifically. If you want to print “ping pong” alternately, just use a generator