Гарантия вызова на уничтожение при прекращении процесса - PullRequest
0 голосов
/ 10 июня 2018

После прочтения МНОГО данных о предмете я все еще не мог найти какое-либо реальное решение моей проблемы (их может и не быть).

Моя проблема заключается в следующем:

В моем проекте у меня есть несколько драйверов, работающих с различными аппаратными средствами (диспетчерами ввода-вывода, программируемыми нагрузками, блоками питания и т. Д.).

Инициализация подключения к этим аппаратным средствам является дорогостоящей (вовремя), и яне могу открыть, а затем закрыть соединение для каждой итерации связи между нами.

Значение Я не могу сделать это (при условии, что программируемая загрузка реализует вход / выход):

start of code...

with programmable_load(args) as program_instance:
     programmable_load_instance.do_something()

rest of code...

Поэтому я выбрал другое решение:

class programmable_load():
    def __init__(self):
         self.handler = handler_creator()
    def close_connection(self):
         self.handler.close_connection()
         self.handler = None
    def __del__(self):
         if (self.handler != None):
             self.close_connection()

По очевидным причинам я не «доверяю» деструктору при вызове, поэтому я явно вызываю close_connection (), когда хочу завершить свою программу (для всех драйверов).

Проблема возникает, когда я резко прекращаю процесс, например, когда я запускаю в режиме отладки и прекращаю отладку.

В этих случаях процессзавершается без запуска через деструкторы.Я понимаю, что ОС на этом этапе очистит всю неиспользуемую память, но есть ли способ очистить память организованным образом?

и, если нет, есть ли способ заставить функцию отладки завершить работуопределенный набор функций?Знает ли процесс python, что он получил довольно отладочное событие, или он рассматривает его как обычное завершение?

Операционная система: Windows

Ответы [ 3 ]

0 голосов
/ 14 июня 2018

Согласно этой документации :

Если процесс завершается с помощью TerminateProcess, все потоки процесса завершаются немедленно без возможности запуска дополнительныхкод.

(выделение мое.) Это означает, что в этом случае вы ничего не можете сделать.

Как подробно здесь , сигналы донне очень хорошо работает на MS-Windows.

0 голосов
/ 19 июня 2018

Я не проверил должным образом, так как у меня не установлена ​​крыло, поэтому я не могу допустить, чтобы это работало, но как насчет использования setconsolectrlhandler ?Например, попробуйте что-то вроде этого:

import os
import sys
import win32api


if __name__ == "__main__":
    def callback(sig, func=None):
        print("Exit handler called!")

    try:
        win32api.SetConsoleCtrlHandler(callback, True)
    except Exception as e:
        print("Captured exception", e)
        sys.exit(1)

    print("Press to quit")
    input()
    print("Bye!")

Он сможет обрабатывать сигналы CTRL+C и CTRL+BREAK:

enter image description here

0 голосов
/ 13 июня 2018

Как уже упоминалось в комментарии, вы можете использовать atexit для очистки.Но это работает, только если процесс попросили закрыть (например, сигнал QUIT в Linux), а не просто уничтожить (как, вероятно, имеет место при остановке сеанса отладки).Точно так же, если вы заставляете компьютер выключаться (например, долго нажимать кнопку питания или отключать питание), он также не будет вызываться.У этого нет «решения» по очевидным причинам.Ваша программа не может быть вызвана при внезапном отключении питания или принудительном отключении.Смысл насильственного убийства состоит в том, чтобы определенно убить процесс сейчас.Если он сначала вызвал ваш код очистки, вы можете отложить то, что противоречит цели.Вот почему существуют такие сигналы, как просьба остановить ваш процесс.Это не специфично для Python.Та же концепция применима и ко всем операционным системам.

Бонус (проектное предложение, а не решение): я бы сказал, что вы все еще можете использовать диспетчер контекста (используя with).Ваша проблема не уникальна.Соединения с базой данных обычно также поддерживаются дольше.Это вопрос объема.Переместите контекст дальше до уровня приложения.Тогда становится ясно, что это за граница, и вам не нужно никакого волшебства (вы, вероятно, также знаете о @contextmanager, чтобы сделать это бризом).

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