用于并发的python生成器

时间:2014-05-16 21:26:17

标签: python concurrency generator

我正在关注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

问题是生成器如何引入并发性以及它是如何表现的?

2 个答案:

答案 0 :(得分:2)

这段代码实现了“绿色线程”的概念,合作,用户态(而不是抢占式,内核)线程。

“线程”是生成器,每个函数都包含yeildyield 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