如何同时运行两个python循环?

hii*_*iii 21 python concurrency

假设我在Python中有以下内容

# A loop
for i in range(10000):
    Do Task A

# B loop
for i in range(10000):
    Do Task B
Run Code Online (Sandbox Code Playgroud)

如何在Python中同时运行这些循环?

Ste*_*zzo 26

如果你想要并发,这是一个非常简单的例子:

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()
Run Code Online (Sandbox Code Playgroud)

这只是我能想到的最基本的例子.请务必阅读http://docs.python.org/library/multiprocessing.html以了解正在发生的事情.

如果你想将数据发送回程序,我建议使用一个队列(根据我的经验,这是最容易使用的).

如果您不介意全局解释器锁,则可以使用线程.进程实例化的成本更高,但它们提供了真正的并发性.


Dav*_*rby 13

为什么要同时运行这两个进程?是因为你认为他们会更快(很有可能他们不会).为什么不在同一个循环中运行任务,例如

for i in range(10000):
    doTaskA()
    doTaskB()
Run Code Online (Sandbox Code Playgroud)

您的问题的明显答案是使用线程 - 请参阅python 线程模块.然而,线程是一个很大的主题,并且有许多陷阱,所以在你走这条路之前先阅读它.

或者,您可以使用python 多处理模块在单独的过程中运行任务.如果两个任务都是CPU密集型,则可以更好地使用计算机上的多个核心.

还有其他选项,例如协同程序,无堆栈tasklet,greenlets,CSP等,但是如果不了解任务A和任务B以及为什么需要同时运行它们,则无法给出更具体的答案.

  • 关于线程模块的一点警告.python有一些它称为全局解释器锁(GIL).即使在单独的线程中,这也会锁定某些(大)python区域同时运行.多处理没有这个问题 - 尽管它有一堆陷阱. (4认同)

ciz*_*ixs 11

您想要的选择有很多种选择:

使用循环

正如许多人所指出的,这是最简单的方法.

for i in xrange(10000):
    # use xrange instead of range
    taskA()
    taskB()
Run Code Online (Sandbox Code Playgroud)

优点:易于理解和使用,无需额外的库.

缺点:taskB必须在taskA之后完成,否则就完成了.它们无法同时运行.

多进程

另一个想法是:同时运行两个进程,python提供进程,以下是一个简单的例子:

from multiprocessing import Process


p1 = Process(target=taskA, args=(*args, **kwargs))
p2 = Process(target=taskB, args=(*args, **kwargs))

p1.start()
p2.start()
Run Code Online (Sandbox Code Playgroud)

优点:任务可以simultaneously在后台运行,你可以控制任务(结束,停止它们等),任务可以交换数据,如果它们竞争相同的资源就可以同步等.

缺点:太重了!操作系统会经常在它们之间切换,即使数据冗余,它们也有自己的数据空间.如果你有很多任务(例如100或更多),那就不是你想要的.

穿线

线程就像进程,只是轻量级.看看这篇文章.它们的用法非常相似:

import threading 


p1 = threading.Thread(target=taskA, args=(*args, **kwargs))
p2 = threading.Thread(target=taskB, args=(*args, **kwargs))

p1.start()
p2.start()
Run Code Online (Sandbox Code Playgroud)

协同程序

库喜欢greenletgevent提供一种叫做coroutines的东西,它应该比线程更快.没有提供示例,如果您有兴趣,请谷歌如何使用它们.

优点:更灵活轻便

缺点:需要额外的库,学习曲线.


Odo*_*ois 8

from threading import Thread
def loopA():
    for i in range(10000):
        #Do task A
def loopB():
    for i in range(10000):
        #Do task B
threadA = Thread(target = loopA)
threadB = Thread(target = loobB)
threadA.run()
threadB.run()
# Do work indepedent of loopA and loopB 
threadA.join()
threadB.join()
Run Code Online (Sandbox Code Playgroud)