我目前正在研究一個小型的python腳本,用於控制我的家用電腦(真的只是一個愛好項目 - 沒有什麼嚴重的)。Python - 編譯後的兩個進程?
劇本里面,有使用線程同時運行(可能開始使用線程代替)兩個線程是這樣的:
thread.start_new_thread(Function, (Args))
其作品的測試腳本時預期......但之後編譯使用Pyinstaller的代碼有兩個進程(每個線程一個 - 我認爲)。
我該如何解決這個問題?
我目前正在研究一個小型的python腳本,用於控制我的家用電腦(真的只是一個愛好項目 - 沒有什麼嚴重的)。Python - 編譯後的兩個進程?
劇本里面,有使用線程同時運行(可能開始使用線程代替)兩個線程是這樣的:
thread.start_new_thread(Function, (Args))
其作品的測試腳本時預期......但之後編譯使用Pyinstaller的代碼有兩個進程(每個線程一個 - 我認爲)。
我該如何解決這個問題?
Python代碼並不需要進行「編譯pyinstaller」
產品,如「Pyinstaller」或「py2exe」是有用的,以創建一個可執行文件,您可以向第三方分發,或重新定位你的電腦裏面而不用擔心Python的安裝 - 但是,他們不會添加「速度」,也不會產生比原來的.py(或Windows上的.pyw)文件更「完成」的二進制文件。
這些產品做的是創建Python itnrepreter的另一個副本,與您的porgram使用的所有模塊都相同,並將它們打包在單個文件中。很可能Pyinstaller會繼續運行第二個進程來檢查主腳本上的內容(例如啓動腳本,也可能有選項以保持腳本運行等)。這不是標準Python程序的一部分。
Pyinstaller不太可能將線程拆分爲2個獨立的進程,因爲這會導致兼容性問題 - 線程在同一進程上運行,並且可以透明地訪問相同的數據結構。
「規範」的Python程序如何運行:主要過程,見O.S.是Python二進制文件(在Windows上是Python.exe) - 它找到了它被調用的Python腳本 - 如果它有一個「.pyc」文件,則加載 - 否則,它加載你的「.py」文件並編譯那對Python字節碼(而不是windwos可執行文件)。此彙編對於運行該程序的人員來說是自動且透明的。它類似於從.java文件到.class的Java編譯 - 但程序員或用戶不需要明確的步驟 - 它是在適當的位置進行的 - 而其他因素控制着Python是否會將生成的字節碼存儲爲.pyc文件與否。
總結:直接運行「.py」腳本沒有性能影響,而不是使用Pyinstaller或其他產品生成.exe文件。但是,如果您使用磁盤空間使用率很低,那麼您將爲每個腳本擁有一個Python解釋器和庫的副本。
Janne Karila在評論中指出的URL釘了它 - 它甚至比我想象的還要糟糕: 爲了運行yioru腳本,pyinstaller在一個臨時目錄中解開Python DLL和模塊。所需要的時間和系統資源與單個腳本運行相比並非微不足道。 http://www.pyinstaller.org/export/v2.0/project/doc/Manual.html?format=raw#how-one-file-mode-works
感謝您的演講......但它仍然沒有讓我更接近爲什麼腳本突然創建兩個進程時,成爲一個獨立的可執行文件。以下是腳本中導入的模塊列表:pythoncom,pyHook,urllib2,time,smtplib,getpass,random,thread,os,psutil,subprocess,math,wmi,inspect,pythoncom,shutil,win32con,win32api,sys,平臺(目前試圖減少導入模塊的數量......) – user1995290
Janne提供的最後鏈接說明了爲什麼有兩個進程:「」「當第一次啓動時,它發現它需要提取這些文件運行「真正的」(...)然後再執行自己。「」「無論如何,我認爲這兩個過程並不相關:從上面的解釋中應該很清楚,您不應該使用Pyinstaller開始用。 – jsbueno
只要從主程序殺死載入程序,如果它真的困擾你。這是一種方法。
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)
[PyInstaller手冊:單文件模式如何工作](http://www.pyinstaller.org/export/v2.0/project/doc/Manual.html?format=raw#how-one-文件模式工作) –