如何并发运行两个Python循环?
假设我在Python中有以下代码
# A loop
for i in range(10000):
Do Task A
# B loop
for i in range(10000):
Do Task B
我该如何在Python中同时运行这些循环呢?
7 个回答
你为什么想同时运行这两个任务呢?是觉得这样会更快吗?其实它们可能并不会更快。为什么不把这两个任务放在同一个循环里一起执行呢?比如:
for i in range(10000):
doTaskA()
doTaskB()
解决你问题的一个明显方法是使用线程——可以看看Python的threading模块。不过,线程这个话题比较复杂,还有很多坑,所以在深入之前最好先了解一下。
另外,你也可以用Python的multiprocessing模块把任务放在不同的进程中运行。如果这两个任务都很耗费CPU资源,这样做可以更好地利用你电脑的多个核心。
还有其他选择,比如协程、无栈任务、绿色线程、CSP等等,但在不了解任务A和任务B的具体情况,以及为什么它们需要同时运行的前提下,很难给出更具体的建议。
你想要的有很多种选择:
使用循环
很多人都提到,这是一种最简单的方法。
for i in xrange(10000):
# use xrange instead of range
taskA()
taskB()
优点:容易理解和使用,不需要额外的库。
缺点:任务B必须在任务A之后完成,或者反之。它们不能同时进行。
多进程
另一种想法是:同时运行两个进程,Python提供了多进程库,下面是一个简单的例子:
from multiprocessing import Process
p1 = Process(target=taskA, args=(*args, **kwargs))
p2 = Process(target=taskB, args=(*args, **kwargs))
p1.start()
p2.start()
优点:任务可以在后台同时
运行,你可以控制任务(结束、停止等),任务之间可以交换数据,如果它们竞争相同的资源,还可以同步等等。
缺点:太重了!操作系统会频繁在它们之间切换,即使数据重复,它们也有自己的数据空间。如果你有很多任务(比如100个或更多),这就不太合适了。
线程
线程就像进程,只是更轻量。可以看看这篇文章。它们的使用方式非常相似:
import threading
p1 = threading.Thread(target=taskA, args=(*args, **kwargs))
p2 = threading.Thread(target=taskB, args=(*args, **kwargs))
p1.start()
p2.start()
协程
像greenlet
和gevent
这样的库提供了一种叫做协程的东西,应该比线程更快。如果你感兴趣,请自行搜索如何使用它们。
优点:更灵活且轻量。
缺点:需要额外的库,学习曲线较陡。
如果你想实现并发,这里有一个非常简单的例子:
from multiprocessing import Process
def loop_a():
while 1:
print("a")
def loop_b():
while 1:
print("b")
if __name__ == '__main__':
Process(target=loop_a).start()
Process(target=loop_b).start()
这只是我能想到的最基本的例子。一定要去看看http://docs.python.org/library/multiprocessing.html,这样你才能理解发生了什么。
如果你想把数据发送回程序,我建议使用队列(根据我的经验,这个用起来最简单)。
如果你不介意全局解释器锁的话,也可以使用线程。进程的创建成本更高,但它们能真正实现并发。