2013-05-01 79 views
0

我有一个程序从数据库中提取“工作”,然后将其分派给工作人员。在python中退出一个线程?

我有一个线程专门做一些循环中的工作。它做的工作来自数据库,并调用得到一个消息阻止:

class MessageThread(Thread): 
    def __init__(self, db, worker_inbox, *args, **kwargs): 
     super(MessageThread, self).__init__(*args, **kwargs) 
     self.db = db 
     self.worker_inbox = worker_inbox # this is a stdlib Queue.Queue 

    def run(self): 
     while True: 
      message = self.db.get() 
      self.worker_inbox.put(message) 

,而不必把一些“标志”到数据库中,有一个很好的方法来阻止这个线程?目前,我正在设置daemon标志,当主线程退出时它会将其杀死,但是我想知道是否有更好的机制或设计方法?

+0

'db'看起来像'Queue'。 db如何定义?为什么不把标记放在'db'中? – unutbu 2013-05-01 14:40:28

+0

当然,'db'是一个队列,但工作被其他各种进程放在那里,所以它不是一个stdlib队列。我不想在数据库中放置一个哨兵 - 这是将实现与数据混合在一起。我宁愿了解是否有这种场景的标准设计架构。 – coleifer 2013-05-01 15:03:55

+0

@coleifer你可以在'.get'上超时吗?如果是的话,那么你可以简单地设置一个共享标志'ALIVE',并使用'while ALIVE:'超时。 – freakish 2013-05-01 15:06:45

回答

0

让您的代码在队列中查找唯一的停止消息。如果它通常传递了一些对象,那么一个说'停止'的字符串是一个很好的快速自记录方式。当它终止工作人员的时候,只需将“停止”放入队列。这唤醒了线程并告诉它完成了。您可以使用布尔值,无或适合您传递的消息的内容。

while True: 
    message = self.db.get() 
    if instance(message, base string) and message == 'stop': 
     break 
    ... 
0

如果db是一个消息队列,那么我会把一些“退出”假消息放到这个队列中。 下面是一些伪代码的外观。

class MessageThread(Thread): 
    def __init__(self, db, worker_inbox, *args, **kwargs): 
     super(MessageThread, self).__init__(*args, **kwargs) 
     self.db = db 
     self.worker_inbox = worker_inbox # this is a stdlib Queue.Queue 

    def run(self): 
     while True: 
      message = self.db.get() 
      if "quit" == message: 
       return 
      self.worker_inbox.put(message) 
    def quit(self): 
     self.db.put("quit") 

a = MessageThread() 
a.start() 
sleep(1.0) 
a.quit() 
a.join()