<bdo id='gXrEN'></bdo><ul id='gXrEN'></ul>
    1. <i id='gXrEN'><tr id='gXrEN'><dt id='gXrEN'><q id='gXrEN'><span id='gXrEN'><b id='gXrEN'><form id='gXrEN'><ins id='gXrEN'></ins><ul id='gXrEN'></ul><sub id='gXrEN'></sub></form><legend id='gXrEN'></legend><bdo id='gXrEN'><pre id='gXrEN'><center id='gXrEN'></center></pre></bdo></b><th id='gXrEN'></th></span></q></dt></tr></i><div id='gXrEN'><tfoot id='gXrEN'></tfoot><dl id='gXrEN'><fieldset id='gXrEN'></fieldset></dl></div>

      <small id='gXrEN'></small><noframes id='gXrEN'>

    2. <legend id='gXrEN'><style id='gXrEN'><dir id='gXrEN'><q id='gXrEN'></q></dir></style></legend>
      <tfoot id='gXrEN'></tfoot>

      PyInstaller 构建的 Windows EXE 因多处理而失败

      时间:2023-05-26
      <legend id='eL8HG'><style id='eL8HG'><dir id='eL8HG'><q id='eL8HG'></q></dir></style></legend>
          <i id='eL8HG'><tr id='eL8HG'><dt id='eL8HG'><q id='eL8HG'><span id='eL8HG'><b id='eL8HG'><form id='eL8HG'><ins id='eL8HG'></ins><ul id='eL8HG'></ul><sub id='eL8HG'></sub></form><legend id='eL8HG'></legend><bdo id='eL8HG'><pre id='eL8HG'><center id='eL8HG'></center></pre></bdo></b><th id='eL8HG'></th></span></q></dt></tr></i><div id='eL8HG'><tfoot id='eL8HG'></tfoot><dl id='eL8HG'><fieldset id='eL8HG'></fieldset></dl></div>
          • <bdo id='eL8HG'></bdo><ul id='eL8HG'></ul>
              <tbody id='eL8HG'></tbody>
            • <small id='eL8HG'></small><noframes id='eL8HG'>

              <tfoot id='eL8HG'></tfoot>

                本文介绍了PyInstaller 构建的 Windows EXE 因多处理而失败的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

                问题描述

                限时送ChatGPT账号..

                在我的项目中,我使用 Python 的 multiprocessing 库在 __main__ 中创建多个进程.该项目正在使用 PyInstaller 2.1.1 打包到单个 Windows EXE 中.

                In my project I'm using Python's multiprocessing library to create multiple processes in __main__. The project is being packaged into a single Windows EXE using PyInstaller 2.1.1.

                我像这样创建新流程:

                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
                

                在 __main__ 中:

                And in __main__:

                if __name__ == '__main__':
                    freeze_support()
                
                    start()
                

                不幸的是,在将应用程序打包成 EXE 并启动它时,我在这一行得到 WindowsError 5 或 6(似乎是随机的):

                Unfortunately, when packaging the application into an EXE and launching it, I get WindowsError 5 or 6 (seems random) at this line:

                command = queue.get_nowait()
                

                PyInstaller 主页上的一个配方声称,在将应用程序打包为单个文件时,我必须修改我的代码以在 Windows 中启用多处理.

                A recipe at PyInstaller's homepage claims that I have to modify my code to enable multiprocessing in Windows when packaging the application as a single file.

                我在这里复制代码:

                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'
                

                我对这个解决方案"的失望在于,第一,完全不清楚它到底在修补什么,第二,它的编写方式如此复杂,以至于无法推断出哪些部分是解决方案,哪些部分是解决方案.只是一个插图.

                My frustration with this "solution" is that, one, it's absolutely unclear what exactly it is patching, and, two, that it's written in such a convoluted way that it becomes impossible to infer which parts are the solution, and which are just an illustration.

                任何人都可以就这个问题分享一些观点,并提供见解在一个项目中究竟需要更改哪些内容,以便在 PyInstaller 构建的单文件 Windows 可执行文件中启用多处理?

                Can anyone share some light on this issue, and provide insight what exactly needs to be changed in a project that enables multiprocessing in PyInstaller-built single-file Windows executables?

                推荐答案

                找到这个PyInstaller后回答我自己的问题票:

                显然我们所要做的就是提供一个如下所示的Process(和_Popen)类,并使用它来代替multiprocessing.Process.我已更正并简化了该类,使其仅适用于 Windows,*ix 系统可能需要不同的代码.

                Apparently all we have to do is provide a Process (and _Popen) class as shown below, and use it instead of multiprocessing.Process. I've corrected and simplified the class to work on Windows only, *ix systems might need different code.

                为了完整起见,以下是上述问题的改编样本:

                For the sake of completeness, here's the adapted sample from the above question:

                import multiprocessing
                from Queue import Empty
                
                class _Popen(multiprocessing.forking.Popen):
                    def __init__(self, *args, **kw):
                        if hasattr(sys, 'frozen'):
                            os.putenv('_MEIPASS2', sys._MEIPASS)
                        try:
                            super(_Popen, self).__init__(*args, **kw)
                        finally:
                            if hasattr(sys, 'frozen'):
                                os.unsetenv('_MEIPASS2')
                
                
                class Process(multiprocessing.Process):
                    _Popen = _Popen
                
                
                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
                

                这篇关于PyInstaller 构建的 Windows EXE 因多处理而失败的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持html5模板网!

                上一篇:如何将python dict与多处理同步 下一篇:Python 3:Pool 是否保持传递给 map 的原始数据顺序

                相关文章

                最新文章

                <tfoot id='SzxQ3'></tfoot>

                  <bdo id='SzxQ3'></bdo><ul id='SzxQ3'></ul>

              1. <small id='SzxQ3'></small><noframes id='SzxQ3'>

                <i id='SzxQ3'><tr id='SzxQ3'><dt id='SzxQ3'><q id='SzxQ3'><span id='SzxQ3'><b id='SzxQ3'><form id='SzxQ3'><ins id='SzxQ3'></ins><ul id='SzxQ3'></ul><sub id='SzxQ3'></sub></form><legend id='SzxQ3'></legend><bdo id='SzxQ3'><pre id='SzxQ3'><center id='SzxQ3'></center></pre></bdo></b><th id='SzxQ3'></th></span></q></dt></tr></i><div id='SzxQ3'><tfoot id='SzxQ3'></tfoot><dl id='SzxQ3'><fieldset id='SzxQ3'></fieldset></dl></div>

                  1. <legend id='SzxQ3'><style id='SzxQ3'><dir id='SzxQ3'><q id='SzxQ3'></q></dir></style></legend>