витой питон INotify без блокировки реактора - PullRequest
1 голос
/ 01 июня 2011

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

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

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

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

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

Спасибо

Simon

Ответы [ 2 ]

7 голосов
/ 01 июня 2011

Все обработчики событий в Twisted работают в «потоке реактора» - UDP, TCP и даже inotify.Ожидается, что все они будут сотрудничать с системой, не блокируя ее.Таким образом, в этом смысле, это всего лишь вопрос о том, как написать хорошие обработчики событий в Twisted, а не о inotify в частности.

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

Использует ли он сокет ввода-вывода?Вместо этого используйте Twisted неблокирующие API-интерфейсы сокета-ввода .

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

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

И т. Д.

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

Кроме того, обратите внимание на Twisted: создание коданеблокирующее для дальнейшего объяснения.

1 голос
/ 01 июня 2011

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

deferToThread(self.created, ignored, path mask)
...