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
相关产品推荐
相关产品推荐

