进程陷入循环 PyInstaller-executable

Processes stuck in loop with PyInstaller-executable

Python v3.5, Windows 10

我正在使用多个进程并尝试捕获用户输入。搜索我看到的所有内容时,在多个进程中使用 input() 时会发生一些奇怪的事情。经过 8 小时以上的尝试,我实施的任何东西都没有奏效,我很肯定我做错了,但我一辈子都弄不明白。

以下是演示该问题的非常精简的程序。现在,当我在 PyCharm 中 运行 这个程序时,它工作正常,但是当我使用 pyinstaller 创建单个可执行文件时,它失败了。该程序不断地陷入循环,要求用户输入如下所示的内容:.

我很确定这与 Windows 如何从我阅读的内容中获取标准输入有关。我也试过将用户输入变量作为 Queue() 项传递给函数,但同样的问题。我读到你应该把 input() 放在主 python 过程中,所以我在 if __name__ = '__main__':

下做了
from multiprocessing import Process
import time


def func_1(duration_1):
    while duration_1 >= 0:
        time.sleep(1)
        print('Duration_1: %d %s' % (duration_1, 's'))
        duration_1 -= 1


def func_2(duration_2):
    while duration_2 >= 0:
        time.sleep(1)
        print('Duration_2: %d %s' % (duration_2, 's'))
        duration_2 -= 1


if __name__ == '__main__':

    # func_1 user input
    while True:
        duration_1 = input('Enter a positive integer.')
        if duration_1.isdigit():
            duration_1 = int(duration_1)
            break
        else:
            print('**Only positive integers accepted**')
            continue

    # func_2 user input
    while True:
        duration_2 = input('Enter a positive integer.')
        if duration_2.isdigit():
            duration_2 = int(duration_2)
            break
        else:
            print('**Only positive integers accepted**')
            continue

    p1 = Process(target=func_1, args=(duration_1,))
    p2 = Process(target=func_2, args=(duration_2,))
    p1.start()
    p2.start()
    p1.join()
    p2.join()

使用 PyInstaller 生成 Windows 可执行文件时需要使用 multiprocessing.freeze_support()

直接从 docs:

multiprocessing.freeze_support()

Add support for when a program which uses multiprocessing has been frozen to produce a Windows executable. (Has been tested with py2exe, PyInstaller and cx_Freeze.)

One needs to call this function straight after the if name == 'main' line of the main module. For example:

from multiprocessing import Process, freeze_support

def f():
    print('hello world!')

if __name__ == '__main__':
    freeze_support()
    Process(target=f).start()

If the freeze_support() line is omitted then trying to run the frozen executable will raise RuntimeError.

Calling freeze_support() has no effect when invoked on any operating system other than Windows. In addition, if the module is being run normally by the Python interpreter on Windows (the program has not been frozen), then freeze_support() has no effect.

在您的示例中,您还应该解决不必要的代码重复问题。