Python: медленное / отложенное выполнение внешней программы при запуске из скрипта с помощью EventLop [Windows] - PullRequest
0 голосов
/ 09 мая 2019

Я столкнулся с очень странной проблемой при запуске внешних программ с python под Windows. Я пытался выяснить, что происходит в течение нескольких недель, и у меня совершенно нет идей.

Проблема

Если я запускаю tool.exe в контексте приложения с графическим интерфейсом с некоторой рабочей нагрузкой сразу после вызова tool.exe, запуск tool.exe задерживается. Окно отображается, но замораживается и становится отзывчивым только после того, как рабочая нагрузка завершится или пройдет от 15 до 30 секунд.

Код

Я приложил 3 версии моего кода для Tk & PySide2. Оба инструментария GUI показывают одинаковое поведение.

Tk Пример

##### Version 1 #####
import subprocess, tkinter, time
subprocess.Popen('tool.exe')
time.sleep(60)


##### Version 2 #####
import subprocess, tkinter, time
tkinter.Tk()
subprocess.Popen('tool.exe')


##### Version 3 #####
import subprocess, tkinter, time
tkinter.Tk()
subprocess.Popen('tool.exe')
time.sleep(60)

Пример PySide2

##### Version 1 #####
from PySide2 import QtWidgets
import subprocess
import time

class Button(QtWidgets.QPushButton):
    def __init__(self):
        super().__init__()
        self.start()

    def start(self):
        subprocess.Popen('tool.exe')
        time.sleep(60)

app = QtWidgets.QApplication()
button = Button()
button.show()
app.exec_()


##### Version 2 #####
from PySide2 import QtWidgets
import subprocess
import time

class Button(QtWidgets.QPushButton):
    def __init__(self):
        super().__init__()
        self.clicked.connect(self.start)

    def start(self):
        subprocess.Popen('tool.exe')

app = QtWidgets.QApplication()
button = Button()
button.show()
app.exec_()


##### Version 3 #####
from PySide2 import QtWidgets
import subprocess
import time

class Button(QtWidgets.QPushButton):
    def __init__(self):
        super().__init__()
        self.clicked.connect(self.start)

    def start(self):
        subprocess.Popen('tool.exe')
        time.sleep(60)

app = QtWidgets.QApplication()
button = Button()
button.show()
app.exec_()

Результат

Версия 1: tool.exe немедленно реагирует

Версия 2: tool.exe немедленно реагирует

Версия 3: tool.exe становится отзывчивым через 15-30 секунд (или после завершения sleep, когда я сокращаю время сна)

Вопрос

Надеюсь, кто-нибудь подскажет мне в правильном направлении, почему это поведение вызвано. Мой сценарий используется десятки раз каждый день, так что эта задержка довольно болезненная. Может быть, я мог бы найти грязный взлом для моей проблемы, но я бы лучше понял, что происходит.

Наконец

  • Я не смог найти инструмент, который показывает подобное поведение. Инструмент является старым проприетарным / коммерческим инструментом для Windows со странной политикой лицензирования. Поэтому, вероятно, аппаратная конфигурация проверяется при запуске инструмента.
  • Я попытался запустить tool.exe через subprocess.Popen, os.startfile и с командным файлом. Под новые установки Windows 7 и Windows 10. Использование флагов создания DETACHED_PROCESS и / или CREATE_NEW_PROCESS_GROUP, close_fds=False/True. Неважно, проблема сохраняется.

Обновление

  • Я попытался запустить tool.exe через threading и multiprocessing. Не помогает.
  • [См. Пример PySide] Всякий раз, когда я возвращаюсь к главному циклу событий после запуска tool.exe, он сразу становится отзывчивым. Так что да, использование threading и multiprocessing возможно для рабочей нагрузки если я не буду ждать их окончания!

Обновление 2

  • Я вроде решил свою проблему, часто выполняя QCoreApplication.processEvents() в моей рабочей нагрузке (как показано sleep(60) выше). Тем не менее, когда я игнорирую все происходящие события, tool.exe загружается просто отлично. Так что секрет остается ...
...