Python - 编译后出现两个进程?

2 投票
2 回答
2936 浏览
提问于 2025-04-17 13:39

我现在在做一个小的Python脚本,用来控制我的家用电脑(其实只是个爱好项目,没什么严肃的)。

在这个脚本里,有两个线程同时运行,使用的是thread(我可能会考虑改用threading),代码大概是这样的:

thread.start_new_thread( Function, (Args) )

在测试脚本的时候,它的运行效果是我想要的……但是在用Pyinstaller编译代码后,出现了两个进程(我觉得是每个线程一个进程)。

我该怎么解决这个问题呢?

2 个回答

-1

Python代码不需要用“pyinstaller”来“编译”。

像“Pyinstaller”或“py2exe”这样的工具可以帮助你创建一个可以分发给其他人的单个可执行文件,或者在你自己的电脑上移动而不需要担心Python的安装问题。不过,它们并不会让程序运行得更快,也不会让生成的文件比你原来的.py(或者在Windows上是.pyw)文件更“完善”。

这些工具的作用是创建一个Python解释器的副本,以及你程序使用的所有模块,并把它们打包成一个文件。Pyinstaller可能会保持一个额外的进程在运行,以检查主脚本的情况(比如启动它,可能还有一些选项让脚本持续运行等等)。这并不是标准Python程序的一部分。

Pyinstaller不太可能把线程分成两个独立的进程,因为那样会导致兼容性问题——线程在同一个进程中运行,可以透明地访问相同的数据结构。

一个“标准”的Python程序是如何运行的呢:操作系统看到的主进程是Python的可执行文件(在Windows上是Python.exe)——它会找到被调用的Python脚本。如果有“.pyc”文件,它会加载这个文件;如果没有,就会加载你的“.py”文件,并把它编译成Python字节码(而不是Windows可执行文件)。这个编译过程是自动的,对运行程序的人来说是透明的。它类似于Java从.java文件编译到.class文件,但程序员或用户不需要进行任何明确的步骤——这个过程是在原地完成的,其他因素决定了Python是否会把生成的字节码存储为.pyc文件。

总结一下:直接运行“.py”脚本并不会影响性能,相比于用Pyinstaller或其他工具生成的.exe文件。不过,如果你这样做,会占用更多的磁盘空间,因为每个脚本都会有一份Python解释器和库的副本。

Janne Karila在评论中提到的链接说得很到位——情况比我想的还要糟糕:为了运行你的脚本,pyinstaller会在一个临时目录中解压Python的DLL和模块。与单个脚本运行相比,这个过程所需的时间和系统资源是相当可观的。

http://www.pyinstaller.org/export/v2.0/project/doc/Manual.html?format=raw#how-one-file-mode-works
3

如果加载器让你很烦,那就直接把它从主程序里干掉吧。这是一个方法。

import os
import win32com.client

proc_name = 'MyProgram.exe'
my_pid = os.getpid()

wmi = win32com.client.GetObject('winmgmts:')
all_procs = wmi.InstancesOf('Win32_Process')

for proc in all_procs:
   if proc.Properties_("Name").Value == proc_name:
        proc_pid = proc.Properties_("ProcessID").Value
        if proc_pid != my_pid:
            print "killed my loader %s\n" % (proc_pid)
            os.kill(proc_pid, 9)

撰写回答