витой питон INotify без блокировки реактора

1

Я использую twsited INotify для мониторинга каталога /dev для мониторинга добавления новых последовательных устройств. Используемый мной код аналогичен приведенному ниже.

notifier = INotify()
notifier.watch(FilePath("/dev"), IN_CREATE, callbacks=[self.created])
notifier.startReading()

def created(self, ignored, path, mask):
    ...
    blocking code
    ...

Проблема, с которой я сталкиваюсь в данный момент, - это когда создается "созданная", она блокирует мой реактор, поэтому другие сетевые сеансы (у меня есть TCP и UDP-соединения, связанные с одним и тем же реактором) должны ждать "созданного" 'для завершения.

Кто-нибудь знает, как я могу заставить "созданный" метод работать в фоновом режиме, чтобы он не блокировал мой реактор?

Спасибо,

Саймон

Теги:
twisted
blocking
inotify

2 ответа

7
Лучший ответ

Все обработчики событий в Twisted run в "потоке реакторов" - UDP, TCP и действительно inotify. Ожидается, что все они будут сотрудничать с системой, не блокируя ее. Итак, в этом смысле это просто вопрос о том, как писать хорошие обработчики событий в Twisted, а не о inotify в частности.

Существует множество вариантов предотвращения блокировки. Трудная вещь в ответе на ваш вопрос заключается в том, что правильный вариант зависит от того, почему именно текущий код блокируется.

Он делает сокеты ввода/вывода? Используйте Twisted non- блокировка API-интерфейс сокета ввода-вывода.

Это делает ввод/вывод файловой системы? Возможно, вам понадобится использовать поток, поскольку non- блокировка файловой системы ввода-вывода затруднена (возможно, не невозможна) без нее.

Говорит ли он с базой данных SQL? Возможно, twisted.enterprise.adbapi может помочь.

И так далее.

Я не знаю, покрывает ли это случай, в котором вы находитесь. Однако я остановлюсь на двух вещах. Во-первых, вполне естественно использовать потоки в программе Twisted. Большая часть Twisted существует, поэтому вам не придется использовать потоки, но если вы придете к тому обстоятельству, когда потоки выполняют свою работу, и ничего больше не делают - идите на это (с осторожностью;). У Twisted даже есть помощники, чтобы облегчить его, например, deferToThread, упомянутый zeekay. Во-вторых, выберите подходящее решение для задачи. Сбор всех "блокирующих" проблем лишь немного меньше, чем сбор всех задач общего программирования. Существует множество возможных решений. Некоторые, например, потоки, похоже, имеют широкий диапазон применимости, но с небольшой осторожностью вы можете найти что-то более подходящее для конкретного обстоятельства.

Кроме того, посмотрите на Twisted: Заблокируйте блокировку non- для дальнейшего объяснения.

  • 0
    Спасибо за вашу помощь и подробный ответ. Я потратил некоторое время на изучение различных опций, которые вы упомянули, и опция deferToThread, похоже, хорошо работает для меня. Что-то, что вы упомянули, однако, выглядит интересно, что вы предложили «Использовать неблокирующие API-интерфейсы ввода / вывода Twisted». Можете ли вы указать мне, где это задокументировано? В очередной раз благодарим за помощь.
  • 1
    просто подробный ответ, который нужен новому искаженному призывнику, как я. большое спасибо!
Показать ещё 1 комментарий
1

Вы можете использовать twisted.internet.threads.deferToThread для запуска вашего блокирующего кода в потоке:

deferToThread(self.created, ignored, path mask)

Ещё вопросы

Сообщество Overcoder
Наверх
Меню