【问题标题】:Python: multithreading in infinite loopPython:无限循环中的多线程
【发布时间】:2017-10-04 09:11:58
【问题描述】:

我有一个基本上运行无限循环的代码,并且在循环的每次迭代中我都会运行一些指令。其中一些指令必须“并行”运行,我通过使用多处理来完成。这是我的代码结构示例:

from multiprocessing import Pool
from multiprocessing.dummy import Pool as ThreadPool 

def buy_fruit(fruit, number):
    print('I bought '+str(number)+' times the following fruit:'+fruit)
    return 'ok'

def func1(parameter1, parameter2):
    myParameters=(parameter1,parameter2)
    pool= Threadpool(2)
    data = pool.starmap(func2,zip(myParameters))
    return 'ok'

def func2(parameter1):
    print(parameter1)
    return 'ok'



while true:
    myFruits=('apple','pear','orange')
    myQuantities=(5,10,2)
    pool= Threadpool(2)
    data = pool.starmap(buy_fruit,zip(myFruits,myQuantities))
    func1('hello', 'hola')

我同意这有点混乱,因为我在主循环中有多个进程,而且在函数中也有。

所以一切正常,直到循环运行几分钟,我得到一个错误: "RuntimeError: 无法启动新线程"

我在网上看到这是因为我打开的线程太多了。

在每次循环迭代结束时关闭所有线程的最简单方法是什么,以便我可以在新循环迭代开始时“重新”重新启动?

提前感谢您的时间和帮助!

最好, 朱莉娅

PS:示例代码只是一个示例,我的真实函数在每个循环中打开了许多线程,每个函数需要几秒钟才能执行。

【问题讨论】:

  • 看看 Pool 的 join() 函数,这可能就是你要找的
  • 您可能想在循环外创建线程池。您可能想在 CPU 绑定线程的上下文中阅读 全局解释器锁。

标签: python multithreading


【解决方案1】:

您正在无限循环中创建一个新的ThreadPool 对象,这可能是导致您的问题的原因,因为您没有在循环结束时终止线程。您是否尝试过在无限循环之外创建对象?

pool = ThreadPool(2)
while True:
    myFruits = ('apple','pear','orange')
    myQuantities = (5,10,2)
    data = pool.starmap(buy_fruit, zip(myFruits,myQuantities))

另外,为了回答您的问题,如果您的用例出于某种原因需要在每次循环迭代中创建一个新的 ThreadPool 对象,请使用 ContextManager (with Notation) 以确保在离开 ContextManager 时关闭所有线程。

while True:
    myFruits = ('apple','pear','orange')
    myQuantities = (5,10,2)
    with ThreadPool(2) as pool:
        data = pool.starmap(buy_fruit, zip(myFruits,myQuantities))

但请注意,这与上述代码相比存在显着的性能差异。创建和终止线程的成本很高,这就是为什么上面的示例运行得更快,并且可能是您想要使用的。

关于涉及“嵌套线程池”的编辑:我建议维护一个线程池实例,并根据需要传递对嵌套函数的引用。

def func1(pool, parameter1, parameter2):
    ...
...

pool = ThreadPool(2)
while True:
    myFruits=('apple','pear','orange')
    myQuantities=(5,10,2)
    data = pool.starmap(buy_fruit, zip(myFruits,myQuantities))
    func1(pool, 'hello', 'hola')

【讨论】:

  • 您好,感谢您的帮助。好的,我想在主循环之外创建池是个好主意。问题是我的代码有点复杂,在主循环中,我调用函数,这些函数也有一些多线程(我编辑了我最初的问题)。有没有办法终止线程?唯一重要的是尽可能同步地执行功能。我不介意在主循环结束时等待关闭所有正在运行的线程。谢谢!
  • 嘿@JuliaScivi。我不太确定您所说的“终止线程”是什么意思。我们在这里使用的ThreadPool 类旨在保持我们告诉它的线程数量,并提供将工作推送到这些线程的方法(例如通过.starmap)。如果您希望能够将工作从另一个函数推送到ThreadPool,只需将它的引用传递给该函数。您的工作将同步执行,因为您只使用同步操作 (starmap)。我编辑了我的答案以说明我的意思
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-06-13
  • 1970-01-01
  • 2012-11-14
  • 1970-01-01
  • 2018-07-03
  • 1970-01-01
相关资源
最近更新 更多