2015-02-17 63 views
0

我有一个运行弹球机的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)?我假设如果我的加载程序线程在等待队列中的项目时只是阻塞,那么这是一种有效的等待类型,我不会浪费一堆循环吗?

谢谢! 布赖恩

回答

1

Queue.get默认为阻止,这是你需要的东西:

卸下并从队列中返回一个项目。如果可选参数块为true并且超时时间为无(默认为),则根据需要进行阻止,直到项目可用。如果超时是一个正数,它将最多阻塞秒数,并在该时间内没有可用项目时引发空例外。否则(block为false),如果一个立即可用,则返回一个项目,否则引发Empty异常(在这种情况下超时被忽略)。

这种方式while循环只对队列中的每个项目运行一次,并在队列为空时被阻塞。

您可以通过在while循环中执行一些可见的事情(如打印输出)来亲自测试它。

如果您正在等待项目,则选项1很好,因为选项2可能会在您获取它们之前终止(如果加载速度足够快)。

该线程可能没有占用足够的资源被视为优化候选人。而且,因为当它不应该运行时你阻止了它,选项1似乎是要走的路。

相关问题