2013-05-01 71 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()