2014-04-13 35 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()