2014-09-14 3 views
2

У меня есть потоковый SMTP-сервер, который занимает дополнительные 20 секунд, чтобы остановиться на Linux (ubuntu 14.04 и fedora 20), чем на OS x (10.8).Нечетное различие в поведении между linux и os x с threaded smtpd в Python 2.7

from email.parser import Parser 
from smtpd import SMTPServer as StdLibSmtpServer 
from smtplib import SMTP 
from threading import Thread 
import asyncore 
import re 
import select 
import logging 
import os.path 
import datetime 
import json 
import random 
from socket import gethostname 
class SmtpServer(StdLibSmtpServer, object): 
    def __init__(self, listen='localhost', port=10025, 
      forward_address='localhost', forward_port=10026): 
     super(SmtpServer, self).__init__((listen, port), None) 
     self.forward_address = forward_address 
     self.forward_port = forward_port 
     self._thread = None 
     self._smtp = SMTP() 
     self._should_re_raise_exceptions = False 
    def start(self): 
     if self._thread: 
      raise Exception("Already running") 
     logging.debug("Starting up") 
     self._thread = Thread(target=self._thread_func) 
     self._thread.daemon = True 
     self._thread.start() 
     logging.info("Started") 
    def stop(self): 
     if not self._thread: 
      raise Exception("Not running") 
     logging.debug("Stopping") 
     self.close() 
     self._thread.join() 
     self._thread = None 
     logging.info("Stopped") 
    def _thread_func(self): 
     try: 
      asyncore.loop() 
     except select.error: 
      pass # socket was closed, we are shutting down 

Это происходит на линии self._thread.join(), и я могу показаться, чтобы выяснить, почему.

Какие-либо рекомендации по устранению этой проблемы? я запускаю файл, выполнив:

from test import SmtpServer 
serv = SmtpServer() 
serv.start() 
serv.stop() 

В serv.stop() является частью, которая является способ медленнее на Linux.

+1

Попробуйте установить значение тайм-аута в 'self._thread.join()' - i.e. 'self._thread.join (timeout = 0.5);' –

ответ

1

Похоже, что основной причиной было asyncore.loop(), требующее установить тайм-аут в системах, которые используют select вместо epoll. Огромное спасибо @binarydud за помощь в этом. Оказывается, что установка короткого тайм-аута на thread.join также работает, но это может привести к асинхронному асинкере.