在单独的线程中运行while循环以检查后台任务

时间:2015-07-09 14:05:57

标签: python multithreading

这会是一种不好的做法,还是有另一种更好的方法来做这样的事情?我目前所拥有的是一个程序,它具有一个CLI菜单系统来获取用户输入,并根据该输入设置查询数据库中的数据,并对其进行分析。

然而,我想要做的是设置查询时使用日期时间启动它,然后将其添加到队列中。最好的情况是,我会把它放在我的菜单系统的事件循环中,但菜单系统在等待用户输入时暂停(通过内置的python input函数或通过curses window.getkey函数)。此外,我希望在分析数据时仍能使用菜单

所以我正在做的是使用两个线程,一个用于检查队列中是否有任何日期时间小于datetime.now()的对象,将其从队列中删除,进行分析,然后继续检查队列。

class AnalysisQueue(threading.Thread):
    def __init__(self, initial_queue):
        super(AnalysisQueue, self).__init__()
        self.alive = True
        self.queue = initial_queue

    def run(self):
        while self.alive: #loop can be terminated externally
            for i,object in enumerate(self.queue):
                if datetime.now() > object.analysis_start:
                    analyse_data(self.queue.pop(i)) #defined elsewhere


class Menu(threading.Thread):
    def __init__(self):
        super(Menu, self).__init__()
        self.date_menu = MultipleChoiceMenu([
            {'description': "Test1"},
            {'description': "Test2"},
            {'description': "Test3"},
        ]) #Menu class that handles display and I/O for the menu

    def run(self):
        self.date_menu.input() #initializes the menu display and waits for input

analysis_thread = AnalysisQueue()
menu_thread = Menu()

analysis_thread.start()
menu_thread.start()
menu_thread.join() #waits for the menu thread to finish (menu is exited)
analysis_thread.alive = False 
#Now that menu has been exited, terminate program.
#whether or not the queue has entries in it at this point is not a concern 

这种方法有什么问题,或者更确切地说,有没有更好的方法呢?

感谢您的帮助!

1 个答案:

答案 0 :(得分:2)

这是一个非常开放的问题,更像是代码审核,但这是我的反馈:

  • 您可以使用priority queue而不是浏览整个列表来查找时间戳。然后你只需要看看队列的头部。
  • 我将self.alivebool更改为Event。它们是线程安全的。
  • 这看起来像是我的常规工作队列,通常用于保持GUI线程的响应。我不明白你的时间戳的原因 - 为什么不立即运行任务?
  • 如何将分析结果传回主线程?
  • 不包括将任务附加到队列的代码。如果您只是在做analysis_thread.queue.append(task),那么您将遇到麻烦 - 因为您的实施是使用列表。列表不是线程安全的(也许附加是原子的,但我不确定pop是),所以你可能需要一些同步。
  • 也许您可以尝试将排队逻辑和工作线程分开。

总之。我会像你一样建立一个工人,并定期Queue任务。也许this是一个好的开始?