在长时间运行的应用程序中使用临时线程?
我有一个运行弹球机的Python应用程序。它需要以相当一致的循环速度运行以进行弹球类型的操作,但是我还需要能够在整个游戏的各个点上加载图像和声音。我没有足够的内存来预加载整个游戏所需的所有声音文件,因此我希望在主游戏循环继续时使用其他线程(或多个线程)在后台加载它们。在长时间运行的应用程序中使用临时线程?
使用Python的threading
模块很容易,因为使用Queue.Queue
来维护需要加载的资产列表。我的问题是,如果资产加载器线程始终运行,是否“OK”(缺少更好的单词),或者我是否应该在需要时创建线程,然后在完成时让它结束。在我的情况下,弹球机和我的Python应用程序一次将运行数小时(或数天)。
所有Python线程的示例我发现它们倾向于应用程序执行某些操作,然后结束,而不是为长时间运行的应用程序创建(可能)临时线程。
在我来说,我想我有两个选择:
选项1,其中装载机线程运行永远:
self.loader_queue = Queue.Queue
def loader_thread(self):
while True:
do_my_work(self.loader_queue.get())
选项2,其中装载机线头当队列为空:
def loader_thread(self):
while not self.loader_queue.empty():
do_my_work(self.loader_queue.get())
很显然,我已经留下了一些东西出来。有些try:
块和创建选项2线程的方法,但是我觉得这些片段解释我两个选项。
我真正的问题是,使用选项1,是“坏”,因为那么我就浪费了一半的Python执行周期,而加载程序线程只是旋转并且对于99.99%的排队时间没有做任何事情空?
或者是这种情况下,我应该使用第一个选项,但使用self.loader_queue.get(block=True)
?我假设如果我的加载程序线程在等待队列中的项目时只是阻塞,那么这是一种有效的等待类型,我不会浪费一堆循环吗?
谢谢! 布赖恩
为Queue.get
默认为阻止,这是你需要的东西:
卸下并从队列中返回一个项目。如果可选参数块为true并且超时时间为无(默认为),则根据需要进行阻止,直到项目可用。如果超时是一个正数,它将最多阻塞秒数,并在该时间内没有可用项目时引发空例外。否则(block为false),如果一个立即可用,则返回一个项目,否则引发Empty异常(在这种情况下超时被忽略)。
这种方式while循环只对队列中的每个项目运行一次,并在队列为空时被阻塞。
您可以通过在while循环中执行一些可见的事情(如打印输出)来亲自测试它。
如果您正在等待项目,则选项1很好,因为选项2可能会在您获取它们之前终止(如果加载速度足够快)。
该线程可能没有占用足够的资源被视为优化候选人。而且,因为当它不应该运行时你阻止了它,选项1似乎是要走的路。