【问题标题】:How to run multiple for loops in parallel under a single function in python如何在python中的单个函数下并行运行多个for循环
【发布时间】:2017-05-17 07:06:41
【问题描述】:

有没有办法为单个函数下的多个 for 循环实现多线程。我知道如果我们有单独的功能可以实现,但是是否可以在同一个功能下拥有它。 例如:

def sqImport():
    for i in (0,50):
        do something specific to 0-49
    for i in (50,100):
        do something specific to 50-99
    for i in (100,150):
        do something specific to 100-149

如果 3 个不同的 for 循环有 3 个单独的函数,那么我们可以这样做:

threadA = Thread(target = loopA)
threadB = Thread(target = loopB)
threadC = Thread(target = loopC)
threadA.run()
threadB.run()
threadC.run()
# Do work indepedent of loopA and loopB 
threadA.join()
threadB.join()
threadC.join()

但是有没有办法在单个函数下实现呢?

【问题讨论】:

  • 可以修改功能吗?
  • 也许multiprocessing.pool.Pool 会激发你的灵感。
  • 你应该尝试 node.js 来实现这个
  • 是的,我可以修改我的函数@exilit

标签: python multithreading python-2.7 python-3.x


【解决方案1】:

首先:如果您打算在生产系统中使用它,我认为您真的应该看看multiprocessing.ThreadPool。我在下面描述的只是一种可能的解决方法(它可能更简单,因此可以用于测试目的)。

您可以将一个 id 传递给函数并使用它来决定您采用哪个循环,如下所示:

from threading import Thread

def sqImport(tId):
    if tId == 0:
        for i in range(0,50):
            print i
    elif tId == 1:
        for i in range(50,100):
            print i
    elif tId == 2:
        for i in range(100,150):
            print i

threadA = Thread(target = sqImport, args=[0])
threadB = Thread(target = sqImport, args=[1])
threadC = Thread(target = sqImport, args=[2])
threadA.start()
threadB.start()
threadC.start()
# Do work indepedent of loopA and loopB 
threadA.join()
threadB.join()
threadC.join()

请注意,我使用了start() 而不是run(),因为run() 不会启动不同的线程,而是在当前线程上下文中执行。此外,我在 for i in range(x,y) 循环中更改了您的 for i in (x, y) 循环,因为我认为,您想要迭代一个范围而不是一个元组(只会迭代 x 和 y)。


使用multiprocessing 的替代解决方案可能如下所示:

from multiprocessing.dummy import Pool as ThreadPool

# The worker function
def sqImport(data):
    for i in data:
        print i


# The three ranges for the three different threads
ranges = [
    range(0, 50),
    range(50, 100),
    range(100, 150)
    ]

# Create a threadpool with 3 threads
pool = ThreadPool(3)
# Run sqImport() on all ranges
pool.map(sqImport, ranges)

pool.close()
pool.join()

【讨论】:

  • 谢谢@exilit。将尝试并检查。
  • @exilit,对于不同的 for 循环,我有不同的打印连接。例如:分别打印“port1”、“port2”、“port3”。对于第一个范围,它应该分别打印'port1'和。我怀疑这会奏效。
【解决方案2】:

您可以使用multiprocessing.ThreadPool,它将您的任务平均分配给正在运行的线程。 关注Threading pool similar to the multiprocessing Pool? 了解更多信息。

如果您真的在寻找并行执行,那么请选择进程,因为线程将面临 python GIL(Global Interpreted Lock)。

【讨论】:

  • 我如何在我的情况下使用它@Hitul?
猜你喜欢
  • 2021-08-21
  • 2020-05-27
  • 2019-03-06
  • 1970-01-01
  • 2021-05-16
  • 2017-01-28
  • 2022-11-15
  • 1970-01-01
  • 2020-12-27
相关资源
最近更新 更多