You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python2中在不同线程运行HTTP与HTTPS服务器问题

解决Python2.7多线程运行HTTP/HTTPS服务器的异常问题

嘿,我一眼就看出你代码里的问题啦——你在创建线程的时候犯了一个很常见的错误:你直接调用了httpd.serve_forever(),而不是把这个函数的引用传给线程。

问题根源

start_new_thread的第一个参数需要是函数对象,但你现在写的start_new_thread(httpd.serve_forever())会立刻执行serve_forever()方法,这会让主线程直接卡在第一个HTTP服务器的无限循环里,根本没机会启动第二个HTTPS线程。而且因为主线程被阻塞了,后面的except KeyboardInterrupt也根本不会触发,自然没法正常关闭服务器。

修复步骤

  1. 正确传递线程函数:把serve_forever作为函数引用传递,而不是调用它,参数用空元组()表示没有额外参数。
  2. 优雅关闭服务器:捕获到KeyboardInterrupt时,调用两个服务器的shutdown()方法来终止serve_forever()的循环,然后等待线程结束。
  3. 推荐用更安全的threading模块:Python2.7的thread模块(start_new_thread属于它)比较底层,threading模块的Thread类更易用且线程管理更安全。

完整修正代码示例

import BaseHTTPServer
import ssl
from threading import Thread

# 定义你的请求处理器(这里用默认的示例处理器)
class SimpleHTTPRequestHandler(BaseHTTPServer.BaseHTTPRequestHandler):
    def do_GET(self):
        self.send_response(200)
        self.end_headers()
        self.wfile.write("Hello from HTTP server!\n")

class SimpleHTTPSRequestHandler(BaseHTTPServer.BaseHTTPRequestHandler):
    def do_GET(self):
        self.send_response(200)
        self.end_headers()
        self.wfile.write("Hello from HTTPS server!\n")

if __name__ == "__main__":
    # 初始化HTTP服务器
    httpd = BaseHTTPServer.HTTPServer(('0.0.0.0', 3000), SimpleHTTPRequestHandler)
    # 初始化HTTPS服务器(使用自签名证书)
    httpsd = BaseHTTPServer.HTTPServer(('0.0.0.0', 3001), SimpleHTTPSRequestHandler)
    httpsd.socket = ssl.wrap_socket(
        httpsd.socket,
        server_side=True,
        certfile='server.crt',  # 你的自签名证书文件
        keyfile='server.key',   # 你的私钥文件
        ssl_version=ssl.PROTOCOL_TLSv1_2
    )

    # 创建线程,注意这里传递的是函数对象,不是调用结果
    http_thread = Thread(target=httpd.serve_forever)
    https_thread = Thread(target=httpsd.serve_forever)

    # 设置线程为守护线程(可选,但主线程退出时会自动终止)
    http_thread.daemon = True
    https_thread.daemon = True

    # 启动线程
    http_thread.start()
    https_thread.start()
    print("HTTP server running on port 3000, HTTPS on 3001. Press Ctrl+C to stop.")

    try:
        # 主线程保持运行,等待用户中断
        while True:
            pass
    except KeyboardInterrupt:
        print("\nClosing the service...")
        # 关闭服务器
        httpd.shutdown()
        httpsd.shutdown()
        # 等待线程结束
        http_thread.join()
        https_thread.join()
        print("Services closed successfully.")

额外说明

  • 确保你已经生成了自签名证书:可以用OpenSSL命令生成:
    openssl req -new -x509 -keyout server.key -out server.crt -days 365 -nodes
    
  • 用threading.Thread代替start_new_thread的好处是可以更方便地管理线程,比如调用join()等待线程结束,设置守护线程等。
  • 主线程里的while True: pass是为了让主线程保持活跃,直到用户按下Ctrl+C,这样才能捕获到中断信号。

内容的提问来源于stack exchange,提问作者x y

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 08:49:06