Python3 HTTP服务while True无限循环阻塞if条件分支执行问题问询
问题原因
Python 标准库默认提供的 HTTPServer 为单线程同步服务模型,同一时间仅能处理一个请求,必须等前一个请求的 do_GET 处理函数完全执行完成后,才会接收处理下一个请求。你在 onAuto 分支中写了 while True 无限循环,会导致 do_GET 函数永远无法返回,整个服务被完全阻塞,自然无法响应后续的其他请求。
解决方案
- 替换单线程
HTTPServer为多线程版本的ThreadingHTTPServer,Python 3.7 及以上版本标准库自带该实现,无需额外安装依赖,每个请求会分配独立线程处理,单个请求阻塞不会影响其他请求的受理。 - 新增全局状态控制开关,避免重复启动
onAuto循环任务,同时可扩展停止循环的接口,不要直接在请求处理函数中运行无限循环,而是将循环逻辑放到独立的后台线程中执行,请求处理函数收到指令后直接返回,不占用请求处理资源。 - 原有的全局
Request变量设计存在线程安全问题,多线程场景下多个请求同时修改会导致值错乱,直接在当前请求的作用域内处理路径判断即可。
修改后参考代码
from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer import subprocess import threading # 自动模式运行开关 auto_running = False # 自动模式后台线程对象 auto_thread = None def always_run(): global auto_running while auto_running: subprocess.run("python3 satu.py", shell=True) subprocess.run("python3 dua.py", shell=True) class RequestHandler_httpd(BaseHTTPRequestHandler): def do_GET(self): messagetosend = bytes('Hello Worldddd!',"utf") self.send_response(200) self.send_header('Content-Type', 'text/plain') self.send_header('Content-Length', len(messagetosend)) self.end_headers() self.wfile.write(messagetosend) # 直接提取当前请求路径,无需全局变量 request_path = self.requestline[5 : int(len(self.requestline)-9)] print(request_path) global auto_running, auto_thread if request_path == 'onAuto': # 避免重复启动 if not auto_running: auto_running = True auto_thread = threading.Thread(target=always_run, daemon=True) auto_thread.start() if request_path == 'offAuto': # 停止自动模式 auto_running = False if auto_thread: auto_thread.join() auto_thread = None if request_path == 'onFM': subprocess.run("python3 satu.py", shell=True) if request_path == 'onQR': subprocess.run("python3 dua.py", shell=True) if request_path == 'offSYS': subprocess.run("python3 OFF_SYSTEM.py", shell=True) return server_address_httpd = ('0.0.0.0',8080) # 替换为多线程HTTP服务器 httpd = ThreadingHTTPServer(server_address_httpd, RequestHandler_httpd) print('Starting Server') httpd.serve_forever()
内容的提问来源于stack exchange,提问作者sya
相关产品推荐
相关产品推荐

