Python потерял контроль над подпроцессом?

Я использую коммерческое приложение, которое использует Python как часть своего скриптового API. Одной из функций является приложение App.run() . Когда эта функция вызывается, она запускает новый Java-процесс, который выполняет оставшуюся часть выполнения. (К сожалению, я действительно не знаю, что он делает под капотом, поскольку поставляемые модули Python являются .pyc файлами, а многие из функций Python генерируются SWIG).

Проблема, с которой я сталкиваюсь, заключается в том, что я создаю App.run() в более крупное приложение Python, которое должно выполнить некоторый гарантированный код очистки (закрытие базы данных и т. Д.). К сожалению, если подпроцесс прерван с помощью Ctrl + C , он прерывается и возвращается в командную строку, не возвращая управление основной программе Python. Таким образом, мой код очистки никогда не выполняется.

До сих пор я пробовал:

  1. Регистрация функции с atexit … не работает
  2. Помещение очистки в класс __del__ destructor … не работает. ( App.run() находится внутри класса)
  3. Создание обработчика сигнала для Ctrl + C в главном приложении Python … не работает
  4. Помещение App.run() в App.run() … приводит к App.run() памяти после Ctrl + C
  5. Помещение App.run() в процесс (из многопроцессорной обработки) … не работает

Любые идеи, что может произойти?

3 Solutions collect form web for “Python потерял контроль над подпроцессом?”

Если try: App.run() finally: cleanup() не работает; вы можете попробовать запустить его в подпроцессе:

 import sys from subprocess import call rc = call([sys.executable, 'path/to/run_app.py']) cleanup() 

Если у вас есть код в строке, вы можете использовать опцию -c например:

 rc = call([sys.executable, '-c', '''import sys print(sys.argv) ''']) 

Вы можете реализовать предложение @ tMC, используя подпроцесс, добавив аргумент preexec_fn=os.setsid (note: no () ), хотя я не вижу, как здесь может помочь создание группы процессов. Или вы можете попробовать shell=True аргумент, чтобы запустить его в отдельной оболочке.

Вы можете попробовать еще раз попробовать многопроцессорность:

 import multiprocessing as mp if __name__=="__main__": p = mp.Process(target=App.run) p.start() p.join() cleanup() 

Это всего лишь контур, но что-то вроде этого?

 import os cpid = os.fork() if not cpid: # change stdio handles etc os.setsid() # Probably not needed App.run() os._exit(0) os.waitpid(cpid) # clean up here 

(os.fork только * nix)

Та же идея может быть реализована с subprocess в агностическом режиме. Идея запускает App.run() в дочернем процессе, а затем ждет завершения дочернего процесса; независимо от того, как завершился детский процесс. На posix вы также можете ловушку для SIGCHLD (смерть от процесса ребенка). Я не гуру окон, поэтому, если это применимо, и subprocess не работает, кому-то еще придется перезвонить.

После App.run() мне будет интересно, как выглядит дерево процессов. Возможно, он запускает exec и перехватывает пространство процесса python. Если это происходит, создание дочернего процесса – единственный способ, которым я могу думать о его улавливании.

Можете ли вы обернуть приложение App.Run () в Try / Catch?

Что-то вроде:

 try: App.Run() except (KeyboardInterrupt, SystemExit): print "User requested an exit..." cleanup() 
  • Вызов сложных C ++-функций в Python (linux)
  • Как «заблокировать клавиатуру», чтобы предотвратить отправку других нажатий на X11 / Linux / Gnome?
  • Как найти точку монтирования файла?
  • Как использовать os.umask () в Python
  • Импортировать библиотеку ошибок ghmm
  • dbus для подключения к сети NetworkManager VPN
  • Пядев - дважды вызывает функцию
  • Загрузка анимации в python
  •  
    Interesting Posts for Van-Lav
    Python - лучший язык программирования в мире.