我正在关注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
问题是生成器如何引入并发性以及它是如何表现的?
答案 0 :(得分:2)
这段代码实现了“绿色线程”的概念,合作,用户态(而不是抢占式,内核)线程。
“线程”是生成器,每个函数都包含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()
在第一个“调度程序”中,我们耗尽第一个线程,然后继续第二个线程。在第二个调度程序中,我们将语句交错出两个线程,首先是我的,然后是你的,然后回到我的。
这是因为在我们可以说第二个调度程序提供并发之前,我们在跨越多个“线程”之间交叉“语句”。
请注意,并发性并不一定意味着并行性。它不是同时执行,只是重叠。
答案 1 :(得分:0)
这里有一个例子可以澄清:
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