2013-11-28 2 views
0

Я построил небольшой многопоточный веб-сервер с помощью this и this. Однако мой поток сервера работает только один раз и останавливается, а не работает навсегда. Ниже мой код:Почему мой многопоточный веб-сервер Python не работает?

import time 
import BaseHTTPServer 
import urlparse 
import urllib 
import SocketServer 
import threading 

HOST_NAME = 'localhost' 
PORT_NUMBER = 8089 


class Handler(BaseHTTPServer.BaseHTTPRequestHandler): 

    def do_HEAD(self): 
     self.send_response(200) 
     self.send_header("Content-type", "text/html") 
     self.end_headers() 

    def do_GET(self): 
     """ Respond to a GET request. """ 

     self.do_HEAD() 

     if self.path == '/vmnum/': 
      response = self.construct_message('Currently there are no VMs running') 
      self.wfile.write(response) 
     elif self.path == '/vmname/': 
      respose = self.construct_message('Your VM is yet to be named') 
      self.wfile.write(respose) 
     else: 
      response = self.construct_message() 
      self.wfile.write(response) 
     return 


    def do_POST(self): 
     """ Respond to a POST request """ 
     length = int(self.headers['Content-Length']) 

     #http://stackoverflow.com/a/12731208/1382297 
     post_data = urlparse.parse_qs(self.rfile.read(length).decode('utf-8')) 
     thread_number = threading.currentThread().getName() 
     lab_name = str(post_data.get('lab-name')[0]) 
     lab_author = str(post_data.get('lab-author')[0]) 

     message = "<p>You successfully created a VM named: " + lab_name + " at the location: " + lab_author + "</p><p>\ 
     \nYou have been served from the thread: " + thread_number 
     respose = self.construct_message(message) 

     self.wfile.write(respose)   
     return 

    def construct_message(self, message=''): 
     message_part1 = "<html><head><title>One VM Per Lab</title></head><body><p>Success!</p>" 
     message_part2 = "<p>You accessed path: " + self.path + "</p>" 
     message_part3 = "</body></html>" 
     return message_part1 + message_part2 + message + message_part3 

class ThreadedHTTPServer(SocketServer.ThreadingMixIn, BaseHTTPServer.HTTPServer): 
    """Handle requests in a separate thread.""" 
    pass 

if __name__ == '__main__': 
    httpd = ThreadedHTTPServer((HOST_NAME, PORT_NUMBER), Handler) 
    try: 
     server_thread = threading.Thread(target=httpd.serve_forever) 
     # Exit the server thread when the main thread terminates 
     server_thread.daemon = True 
     server_thread.start() 
     print "Server Started - %s:%s with the thread :%s" % (HOST_NAME, PORT_NUMBER, server_thread.name) 
    except KeyboardInterrupt: 
     httpd.server_close() 
    print "Server Stopped - %s:%s" % (HOST_NAME, PORT_NUMBER) 

Когда я бегу выше сценарий, я получаю следующее:

Server Started - localhost:8089 with the thread :Thread-1 
Server Stopped - localhost:8089 

Если я мой сервер без многопоточных [т.е. он не будет иметь серверный поток, тогда он будет работать отлично]. Обратите внимание, что это будет по-прежнему многопоточной порождая новый поток для каждого запроса

if __name__ == '__main__': 
    httpd = ThreadedHTTPServer((HOST_NAME, PORT_NUMBER), Handler) 
    print "Server Started - %s:%s" % (HOST_NAME, PORT_NUMBER) 
    try: 
     httpd.serve_forever() 
    except KeyboardInterrupt: 
     httpd.server_close() 
    print "Server Stopped - %s:%s" % (HOST_NAME, PORT_NUMBER) 

ответ

1

Ваш основной поток должен блокировать что-то. В противном случае он просто вызывает server_thread.start(), а затем переходит к вызову print "Server stopped - ....

Рассмотрите возможность поместить server_thread.join() после того, как ваша линия print "Server Started....

Смотрите также http://docs.python.org/2/library/threading.html#threading.Thread.join

+0

Можете ли вы привести мне пример или любую ссылку, которая объясняет это? Если посмотреть на официальный код документов, кажется, что запросы отправляются из того же сценария после запуска сервера. Таким образом, он выполняет те, а затем отключается. Как мне добиться того же самого с моим кодом? – avi

+0

@avi обновленный ответ – kkurian

0

От the docs:

Нить может быть помечен как «демон нить». Значение этого флага заключается в том, что вся программа Python завершается, когда остаются только потоки демона.

Так как ваш основной поток завершается вызовом print "Server Stopped ..., все ваши потоки демонов отключены.

Кратчайшее, но, вероятно, не лучшее решение для приостановки выполнения потока и ожидания прерывания клавиатуры, добавление бесконечного цикла. Ваш поток демона будет умирать без вашего основного потока.

try: 
    while True: 
     time.sleep(1) 
except (KeyboardInterrupt, SystemExit): 
    print "Server Stopped - %s:%s" % (HOST_NAME, PORT_NUMBER) 
+0

Я не установил значение потока демона в true. Это работает, но не совсем то, на что я надеюсь. Сначала он печатает, что он запущен и сразу же печатает, что он остановлен. Затем я отправил запрос, он ответил. А также прерывание клавиатуры не остановило его, скорее мне пришлось принудительно закрыть терминал. – avi

+0

Я прокомментировал эту строку, когда я бежал теперь: P – avi

+0

«и он не контролирует поток выполнения процессов демонов», да, так как я могу его контролировать? и извините за мой плохой английский. – avi

Смежные вопросы