Trong dự án của tôi, tôi đang sử dụng thư viện multiprocessing
của Python để tạo nhiều quy trình trong __main__. Dự án đang được đóng gói thành một Windows EXE duy nhất sử dụng PyInstaller 2.1.1.Windows EXE PyInstaller được xây dựng không thành công với đa xử lý
tôi có thể tạo quy trình mới như sau:
from multiprocessing import Process
from Queue import Empty
def _start():
while True:
try:
command = queue.get_nowait()
# ... and some more code to actually interpret commands
except Empty:
time.sleep(0.015)
def start():
process = Process(target=_start, args=args)
process.start()
return process
Và trong __main__:
if __name__ == '__main__':
freeze_support()
start()
Thật không may, khi đóng gói ứng dụng thành một EXE và khởi chạy nó, tôi nhận được WindowsError
5 hoặc 6 (dường như ngẫu nhiên) tại dòng này:
command = queue.get_nowait()
Công thức tại trang chủ của PyInstaller cho rằng Tôi phải sửa đổi mã của mình để cho phép đa xử lý trong Windows khi đóng gói ứng dụng dưới dạng một tệp.
Tôi đang tái tạo mã ở đây:
import multiprocessing.forking
import os
import sys
class _Popen(multiprocessing.forking.Popen):
def __init__(self, *args, **kw):
if hasattr(sys, 'frozen'):
# We have to set original _MEIPASS2 value from sys._MEIPASS
# to get --onefile mode working.
# Last character is stripped in C-loader. We have to add
# '/' or '\\' at the end.
os.putenv('_MEIPASS2', sys._MEIPASS + os.sep)
try:
super(_Popen, self).__init__(*args, **kw)
finally:
if hasattr(sys, 'frozen'):
# On some platforms (e.g. AIX) 'os.unsetenv()' is not
# available. In those cases we cannot delete the variable
# but only set it to the empty string. The bootloader
# can handle this case.
if hasattr(os, 'unsetenv'):
os.unsetenv('_MEIPASS2')
else:
os.putenv('_MEIPASS2', '')
class Process(multiprocessing.Process):
_Popen = _Popen
class SendeventProcess(Process):
def __init__(self, resultQueue):
self.resultQueue = resultQueue
multiprocessing.Process.__init__(self)
self.start()
def run(self):
print 'SendeventProcess'
self.resultQueue.put((1, 2))
print 'SendeventProcess'
if __name__ == '__main__':
# On Windows calling this function is necessary.
if sys.platform.startswith('win'):
multiprocessing.freeze_support()
print 'main'
resultQueue = multiprocessing.Queue()
SendeventProcess(resultQueue)
print 'main'
thất vọng của tôi với điều này "giải pháp" là, một, nó hoàn toàn không rõ ràng chính xác những gì nó được vá, và, hai, rằng nó được viết bằng như một cách phức tạp mà nó trở thành không thể suy ra phần nào là giải pháp, và đó chỉ là một minh họa.
Bất kỳ ai cũng có thể chia sẻ một chút về vấn đề này và cung cấp thông tin chi tiết về chính xác những gì cần được thay đổi trong một dự án cho phép đa xử lý trong tệp thực thi Windows đơn tệp PyInstaller?
Công thức có khắc phục được sự cố không? – dano
Vâng, không rõ ràng (ít nhất là với tôi) cách áp dụng công thức. Chỉ cần dán mã ở trên trong tập lệnh Python chính của tôi cũng không hoạt động, vì nó làm tăng thêm hai ngoại lệ không liên quan đến các kịch bản lệnh Python của tôi. Mà nói với tôi rằng công thức về cơ bản là thiếu sót. – nikola
Nếu bạn chỉ chạy công thức dưới dạng tập lệnh độc lập, nó có chạy không có lỗi không? – dano