[英]python generators for concurrency
我正在关注 Python 大师 David Beazley 的幻灯片。 它指出“生成器也用于并发。这是一个例子:
from collections import deque
def countdown(n):
while n > 0:
print("T-minus", n)
yield
n -=1
def countup(n):
x = 0
while x > n:
print("Up we go", x)
yield
x +=1
# instantiate some tasks in a queue
tasks = deque([countdown(10),
countdown(5),
countup(20)
])
# run a little scheduler
while tasks:
t = tasks.pop() # get a task
try:
next(t) # run it until it yields
tasks.appendleft(t) # reschedule
except StopIteration:
pass
这是输出:
T-minus 5
T-minus 10
T-minus 4
T-minus 9
T-minus 3
T-minus 8
T-minus 2
T-minus 7
T-minus 1
T-minus 6
T-minus 5
T-minus 4
T-minus 3
T-minus 2
T-minus 1
问题是生成器是如何引入并发性的,它是如何表现出来的?
这段代码实现了“绿色线程”、协作、用户空间(相对于抢占式、内核)线程的概念。
“线程”是生成器,每个函数都包含yeild
或yield from
。 显然,调度程序存在于if __name__ == '__main__':
位中。
因此,假设我们没有生成器,而是常规列表,并且每个列表中都有一个函数序列。
def doThis(): pass
def sayThis(): pass
def doThat(): pass
...
myThread = [doThis, doThat, doAnother]
yourThread = [sayThis, sayThat, sayAnother]
我们可以按顺序运行所有函数:
for thread in [myThread, yourThread]:
for stmt in thread:
stmt()
或者我们可以按其他顺序进行:
for myStmt, yourStmt in zip(myThread, yourThread):
myStmt()
yourStmt()
在第一个“调度器”中,我们耗尽了第一个线程,然后再进行第二个线程。 在第二个调度程序中,我们将两个线程中的语句交织在一起,首先是我的,然后是你的,然后是我的。
这是因为我们在耗尽那些线程之前在多个“线程”中交错“语句”,我们可以说第二个调度程序提供并发性。
请注意,并发并不一定意味着并行。 这不是同时执行,只是重叠。
这是一个澄清的例子:
from collections import deque
def coro1():
for i in range(1, 10):
yield i
def coro2():
for i in range(1, 10):
yield i*10
print('Async behaviour'.center(60, '#'))
tasks = deque()
tasks.extend([coro1(), coro2()])
while tasks:
task = tasks.popleft() # select and remove a task (coro1/coro2).
try:
print(next(task))
tasks.append(task) # add the removed task (coro1/coro2) for permutation.
except StopIteration:
pass
出去:
######################Async behaviour#######################
1
10
2
20
3
30
4
40
5
50
6
60
7
70
8
80
9
90
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.