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

Django多线程程序经PyInstaller打包为exe后出现无限循环

问题原因

PyInstaller打包成exe后,sys.executable指向的是生成的exe文件,而非原始Python解释器。你的代码通过subprocess.run([sys.executable, 'manage.py', ...])启动新进程时,相当于再次运行了这个exe,导致无限递归启动进程,也就是你看到的无限循环。

解决方案

直接在线程中调用Django内置的命令执行函数,无需通过subprocess启动新进程,既避免循环问题,也减少系统开销。

修改后的代码如下:

# run_both.py
import os
from threading import Thread
import sys
import django
from django.core.management import execute_from_command_line

# 设置Django配置模块
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'project.settings')
django.setup()

def run_django_server():
    print("Starting Django server...")
    # 直接调用Django命令执行函数
    execute_from_command_line(['manage.py', 'runserver'])
    print("Django server finished.")

def run_custom_command():
    print("Running custom command...")
    # 直接调用自定义命令
    execute_from_command_line(['manage.py', 'run_file_watcher'])
    print("Custom command finished.")

if __name__ == "__main__":
    thread1 = Thread(target=run_django_server)
    thread2 = Thread(target=run_custom_command)
    # 设置为守护线程,确保主线程退出时子线程也终止(可选,根据需求调整)
    thread1.daemon = True
    thread2.daemon = True
    thread1.start()
    thread2.start()
    
    # 主线程等待子线程结束,避免程序直接退出
    thread1.join()
    thread2.join()
额外说明
  • 原来的subprocess方式会启动新进程,打包后新进程会再次触发exe执行,形成循环。改用execute_from_command_line直接在当前进程的线程中执行Django命令,从根源避免了这个问题。
  • 添加thread.join()是为了让主线程等待子线程完成,否则主线程可能提前退出,导致子线程被强制终止。
  • 如果你的自定义命令依赖独立进程环境,可以考虑在打包时指定原始Python解释器路径,但这种方式不如直接调用命令函数可靠。

内容的提问来源于stack exchange,提问作者ahmed tahri

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 00:31:04