进程卡死在PyInstaller-executable中 [英] Processes stuck in loop with PyInstaller-executable

查看:196
本文介绍了进程卡死在PyInstaller-executable中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Python v3.5,Windows 10

我正在使用多个过程,并试图捕获用户输入.搜索所有内容,发现将input()与多个进程一起使用时,会发生奇怪的事情.经过8个多小时的尝试,我没有实施任何措施,我很确定自己做错了,但我一生都无法解决.

I'm using multiple processes and trying to captures user input. Searching everything I see there are odd things that happen when using input() with multiple processes. After 8 hours+ of trying, nothing I implement worked, I'm positive I am doing it wrong but I can't for the life of me figure it out.

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

The following is a very stripped down program that demonstrates the issue. Now it works fine when I run this program within PyCharm, but when I use pyinstaller to create a single executable it fails. The program constantly is stuck in a loop asking the user to enter something as shown below:.

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

I am pretty sure it has to do with how Windows takes in standard input from things I've read. I've also tried passing the user input variables as Queue() items to the functions but the same issue. I read you should put input() in the main python process so I did that under 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().

You need to use multiprocessing.freeze_support() when you produce a Windows executable with PyInstaller.

直接从文档

multiprocessing.freeze_support()

增加对冻结使用多处理程序的程序以生成Windows可执行文件的支持. (已经使用py2exe,PyInstaller和cx_Freeze进行了测试.)

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.)

需要在主模块的if name ==' main '行之后直接调用此函数.例如:

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()

如果省略了Frozen_support()行,则尝试运行冻结的可执行文件将引发RuntimeError.

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

在Windows以外的任何操作系统上调用freeze_support()均无效.另外,如果该模块由Windows上的Python解释器正常运行(该程序尚未冻结),则freeze_support()无效.

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.

在您的示例中,您还应该处理不必要的代码重复.

In your example you also have unnecessary code duplication you should tackle.

这篇关于进程卡死在PyInstaller-executable中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆