2014-04-13 37 views
0

我最好從代碼開始提問。定時器線程的終止過程

from multiprocessing import Process, Event, Queue 
from threading import Timer 
from Queue import Empty 

class MyServer(Process): 
    def __init__(self, port, queue): 
     Process.__init__(self) 

     self.port = port 
     self.queue = queue 
     self.sd = None 

    def run(self): 
     try: 
      self.start_serving() 

     except KeyboardInterrupt: 
      print("Shutting down..") 

     finally: 
      if self.sd is not None: 
       self.sd.close() 

    def start_serving(self): 
     s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
     s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) 
     self.sd = s 
     try: 
      s.bind(('', self.port)) 
      s.listen(1) 
      while True: 
       conn, addr = s.accept() 
       while True: 
        # I dont want to bore you with excess code 
        # just recv data from clients 
        try: 
         msg = self.queue.get_nowait() 
         # here i start Timer with delay from message (I'll describe Message class below) 
         Timer(msg.delay, self.response_handler, args=(conn, msg)).start() 
        except Empty: 
         pass 
       conn.close() 

     finally: 
      s.close() 

    def response_handler(self, sd, msg): 
     # doesn't matter 
     # and now I want to terminate the MyServer instance 
     if msg.terminate: 
      # the problem is here. Lets call it 'problem line' 
      sys.exit() 

msgMessage類,這是實例:

class Message(object): 
    def __init__(self, port, delay, values, terminate=False): 
     self.port = port 
     self.delay = delay 
     self.values = values 
     self.terminate = terminate 

的邏輯是我通過TCP連接從獲取客戶端的數據,並檢查隊列用於消息。消息是控制服務器的東西。有時我收到一條消息,如「等待3秒鐘並終止服務器」。 迄今爲止我所做的一切。

  1. 致電self.terminate()problem line。我得到 AttributeError: 'NoneType' object has no attribute 'terminate'
  2. problem line引發異常。我認爲這個例外被run()函數捕獲。我是 錯誤
  3. 致電sys.exit()。它也行不通。

也許我的問題可以縮短。如何從Python的線程中終止進程?

+0

嗨,你有沒有設法解決這個問題? –

+0

@ShiftyScales我的歉意,我不記得細節。我很可能使用了下面答案和其他一些代碼中的一些混合解決方案。 – Deck

回答

2

爲什麼不使用multiprocessing.Event(您已經在導入它),並且如果您收到終止消息,請優雅退出進程。

要做到這一點它添加到__init__

self.exit = Event() 

而改變兩個while循環:

while True: 
    conn, addr = s.accept() 
    while True: 
    #... 

while not self.exit.is_set(): 
    conn, addr = s.accept() 
    while not self.exit.is_set() 
    #... 

然後在響應處理:

if msg.terminate: 
    self.exit.set() 

這將允許代碼自然退出循環,確保調用conn.close()