Процессы, застрявшие в цикле с исполняемым файлом PyInstaller - PullRequest
0 голосов
/ 06 января 2019

Python v3.5, Windows 10

Я использую несколько процессов и пытаюсь перехватить ввод пользователя. При поиске всего, что я вижу, происходят странные вещи, которые возникают при использовании input() с несколькими процессами. После 8 часов + попыток ничего, что я реализовал, не сработало, я уверен, что делаю это неправильно, но я не могу понять, насколько я понимаю.

Ниже приведена очень урезанная программа, демонстрирующая проблему. Теперь он работает нормально, когда я запускаю эту программу в PyCharm, но когда я использую pyinstaller для создания одного исполняемого файла, это не удается. Программа постоянно зацикливается, прося пользователя ввести что-то, как показано ниже: enter image description here.

Я почти уверен, что это связано с тем, как 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()

1 Ответ

0 голосов
/ 07 января 2019

Вам необходимо использовать multiprocessing.freeze_support() при создании исполняемого файла Windows с PyInstaller.

Прямо из документов :

multiprocessing.freeze_support ()

Добавлена ​​поддержка, когда программа, использующая многопроцессорную обработку, была заморожена для создания исполняемого файла Windows. (Протестировано с py2exe, PyInstaller и cx_Freeze.)

Эту функцию нужно вызывать сразу после строки name == ' main ' основного модуля. Например:

from multiprocessing import Process, freeze_support

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

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

Если строка freeze_support () опущена, то попытка запустить замороженный исполняемый файл вызовет RuntimeError.

Вызов freeze_support () не действует при вызове в любой операционной системе, кроме Windows. Кроме того, если модуль нормально запускается интерпретатором Python в Windows (программа не была заморожена), то freeze_support () не действует.

В вашем примере у вас также есть ненужное дублирование кода, которое вы должны решить.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...