为什么我的多线程Python Web服务器失败了?

时间:2013-11-28 19:18:03

标签: python multithreading web-services

我在thisthis的帮助下构建了一个小型多线程Web服务器。但是我的服务器线程只运行一次并停止,而不是永远运行。以下是我的代码:

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)

2 个答案:

答案 0 :(得分:1)

您的主线程需要阻止某些事情。否则,它只需调用server_thread.start(),然后继续调用print "Server stopped - ...

考虑在server_thread.join()行之后添加print "Server Started...

另见http://docs.python.org/2/library/threading.html#threading.Thread.join

答案 1 :(得分: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)