简体   繁体   English

Python:无限循环中的多线程

[英]Python: multithreading in infinite loop

I have a code which is basically running an infinite loop, and in each iteration of the loop I run some instructions. 我有一个基本上运行无限循环的代码,并且在循环的每次迭代中,我都会运行一些指令。 Some of these instructions have to run in "parallel", which I do by using multiprocessing. 其中一些指令必须以“并行”方式运行,这是通过使用多处理来完成的。 Here is an example of my code structure: 这是我的代码结构的示例:

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')

I agree it's a bit messy, because I have multi-processes within the main loop, but also within functions. 我同意这有点混乱,因为我在主循环中还有函数中都有多个进程。

So everything works well, until the loop runs a few minutes and I get an error: "RuntimeError: can't start new thread" 因此一切正常,直到循环运行几分钟,然后出现错误:“ RuntimeError:无法启动新线程”

I saw online that this is due to the fact that I have opened too many threads. 我在网上看到这是由于我打开了太多线程这一事实。

What is the simplest way to close all my Threads by the end of each loop iteration, so I can restart "fresh" at the start of the new loop iteration? 在每个循环迭代结束之前关闭所有线程的最简单方法是什么,这样我就可以在新的循环迭代开始时重新启动“全新”操作?

Thank you in advance for your time and help! 预先感谢您的时间和帮助!

Best, Julia 最好,朱莉娅

PS: The example code is just an example, my real function opens many threads in each loop and each function takes a few seconds to execute. PS:该示例代码仅是一个示例,我的真实函数在每个循环中打开许多线程,并且每个函数需要花费几秒钟来执行。

You are creating a new ThreadPool object inside the endless loop, which is a likely cause to your problem, because you are not terminating the threads at the end of the loop. 您正在无限循环内创建一个新的ThreadPool对象,这可能是导致问题的原因,因为您没有在循环结束时终止线程。 Have you tried creating the object outside of the endless loop? 您是否尝试过在无限循环之外创建对象?

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

Alternatively, and to answer your question, if your use case for some reason requires creating a new ThreadPool Object in each loop iteration, use a ContextManager ( with Notation) to make sure all threads are closed upon leaving the ContextManager. 另外,要回答您的问题,如果您的用例由于某种原因需要在每次循环迭代中创建一个新的ThreadPool对象,请使用ContextManager( with符号)来确保所有线程在退出ContextManager时均已关闭。

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

Notice however the noticable performance difference this has compared to the above code. 但是请注意,与上面的代码相比,这存在明显的性能差异。 Creating and terminating Threads is expensive, which is why the example above will run much faster, and is probably what you'll want to use. 创建和终止线程非常昂贵,这就是为什么上面的示例将运行得更快的原因,并且可能是您想要使用的。

Regarding your edit involving "nested ThreadPools": I would suggest to maintain one single instance of your ThreadPool, and pass references to your nested functions as required. 关于涉及“嵌套ThreadPool”的编辑:我建议维护ThreadPool的一个实例,并根据需要将引用传递给嵌套函数。

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')

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM