Какая библиотека асинхронного Python лучше всего подходит для моего кода? Asyncore? Витая?

У меня есть программа, над которой я работаю, которая будет считываться из двух «сетевых источников» одновременно. Я хотел попробовать асинхронный подход, а не использовать потоки. Это заставило меня задуматься о том, какую библиотеку использовать …

Я придумал простой примерный код, который демонстрирует, что моя программа будет делать:

import sniffer def first(): for station in sniffer.sniff_wifi(): log(station.mac()) def second(): for station in sniffer.sniff_ethernet(): log(station.mac()) first() second() 

Два метода sniffer выглядят примерно так:

 def sniff_wifi(self): while True: yield mac_address 

В while True цикл явно блокирует их.

Я хочу использовать asyncore для этого, поскольку он является частью стандартной библиотеки. Никакие зависимости от третьей стороны не являются бонусом. Однако это не значит, что я не буду использовать его, если вы порекомендуете …

Могу ли я достичь того, что я пытаюсь сделать с помощью asyncore? Если да, не могли бы вы показать мне, как преобразовать код примера в «асинхронный код»? Знаете ли вы о каких-либо хороших асинхронных учебниках?

    3 Solutions collect form web for “Какая библиотека асинхронного Python лучше всего подходит для моего кода? Asyncore? Витая?”

    Twisted лучше в любом случае. Это более портативный, более функциональный, простой, более масштабируемый, лучше поддерживается, лучше документирован, и он может сделать вкусный омлет. Asyncore, по сути, устарел.

    Трудно продемонстрировать все способы, с помощью которых Twisted превосходит короткий ответ (как я могу продемонстрировать сервер http / dns / ssh / smtp / pop / imap / irc / xmpp / process-spawning / multi-threading в коротком примере ?), поэтому вместо этого я сосредоточусь на одном из самых распространенных заблуждений, которые люди, похоже, имеют о Twisted: это как-то более сложно или сложнее в использовании, чем asyncore.

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

    Во-первых, вот сервер:

     import asyncore, socket class Server(asyncore.dispatcher): def __init__(self, host, port): asyncore.dispatcher.__init__(self) self.create_socket(socket.AF_INET, socket.SOCK_STREAM) self.bind(('', port)) self.listen(1) def handle_accept(self): socket, address = self.accept() print 'Connection by', address EchoHandler(socket) class EchoHandler(asyncore.dispatcher_with_send): def handle_read(self): self.out_buffer = self.recv(1024) if not self.out_buffer: self.close() s = Server('', 5007) asyncore.loop() 

    и вот клиент:

     import asyncore, socket class Client(asyncore.dispatcher_with_send): def __init__(self, host, port, message): asyncore.dispatcher.__init__(self) self.create_socket(socket.AF_INET, socket.SOCK_STREAM) self.connect((host, port)) self.out_buffer = message def handle_close(self): self.close() def handle_read(self): print 'Received', self.recv(1024) self.close() c = Client('', 5007, 'Hello, world') asyncore.loop() 

    Есть несколько неясных случаев, когда этот код работает неправильно, но объяснение их скучно и сложно, и код уже достаточно долго ответил на этот вопрос.

    Теперь вот какой код, который делает в основном то же самое, с Twisted. Во-первых, сервер:

     from twisted.internet import reactor, protocol as p class Echo(p.Protocol): def dataReceived(self, data): self.transport.write(data) class EchoFactory(p.Factory): def buildProtocol(self, addr): print 'Connection by', addr return Echo() reactor.listenTCP(5007, EchoFactory()) reactor.run() 

    И теперь, клиент:

     from twisted.internet import reactor, protocol as p class EchoClient(p.Protocol): def connectionMade(self): self.transport.write(self.factory.data) def dataReceived(self, data): print 'Received:', data self.transport.loseConnection() class EchoClientFactory(p.ClientFactory): protocol = EchoClient def __init__(self, data): self.data = data reactor.connectTCP('localhost', 5007, EchoClientFactory('Hello, world')) reactor.run() 

    Есть несколько вещей, на которые я хотел бы обратить ваше внимание. Прежде всего, пример Twisted на 25% короче, даже для чего-то такого тривиального. 40 строк для asyncore, всего 30 для Twisted. По мере того как ваш протокол становится более сложным, эта разница будет становиться все больше и больше, так как вам нужно написать все больше и больше кода поддержки для асинхронных операций, которые были бы предоставлены вам Twisted.

    Во-вторых, Twisted обеспечивает полную абстракцию . С примером asyncore вы должны использовать модуль socket для создания реальной сети; asyncore обеспечивает только мультиплексирование. Это проблема, если вам требуется переносимое поведение на таких платформах, как Windows . Это также означает, что в asyncore полностью отсутствуют возможности для асинхронной коммуникации подпроцесса на других платформах; вы не можете записывать произвольные дескрипторы файлов в вызов select() в Windows.

    В-третьих, пример Twisted – нейтральный транспорт . Ни один из Echo и EchoFactory и EchoClient и EchoClientFactory имеет никакого отношения к TCP. Вы можете превратить эти классы в библиотеку, которая может быть подключена через SSH или SSL или сокет UNIX или канал, только путем изменения connectTCP / listenTCP внизу. Это важно, так как поддержка чего-то типа TLS непосредственно в вашей логике протокола очень сложна. Например, «запись» в TLS вызовет «чтение» на более низком уровне. Таким образом, вам нужно отделить эти проблемы, чтобы исправить их.

    Наконец, специфический для вашего прецедента, если вы имеете дело с MAC-адресами и сетями Ethernet напрямую, Twisted содержит Twisted Pair , низкоуровневую библиотеку для работы с сетями IP и ethernet. Это не самая активно поддерживаемая часть Twisted; код довольно старый. Но он должен работать, и если это не так, мы будем серьезно относиться к любым ошибкам и (в конечном итоге) видеть, что они исправляются. Насколько мне известно, для асинкора нет сопоставимой библиотеки, и она, конечно же, не содержит никакого такого кода.

    Asyncore приятный, но не очень богатый, поэтому вы можете столкнуться с проблемами позже, когда ваше приложение растет. Это, как говорится, здорово прототип материала. Подход довольно прост. Вы определяете методы обработки определенных событий в классе (когда чтение возможно, когда запись возможна и т. Д.), А затем подкласс, который из класса asyncore.dispatcher (я думаю).

    Официальные документы для модуля, а также превосходная статья PyMOTW от Doug Hellmann об этом являются хорошими источниками для проверки документов и примеров.

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

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

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

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

     
    Interesting Posts for Van-Lav

    Неожиданно перечислены изменения списков, отображаемые в подсписках

    Python – найти путь к запущенному файлу

    redis.exceptions.ConnectionError: Ошибка -2 подключение к localhost: 6379. Имя или услуга неизвестны

    Ширины столбцов (из нескольких столбцов) в Openpyxl становятся равными нулю после 60 + столбцов

    Каков наилучший способ создания обменных ключей для одного значения словаря?

    глобальная переменная django

    Устанавливать различия в столбцах между кадрами данных

    Как получить доступ к 2 спискам за раз, глядя вперед с izip_longest? -Python

    ошибка: видеосистема не инициализирована; Есть ли решение?

    Python, как читать N количество строк за раз

    Selenium, выбор элемента внутри <span>

    Flask App: обновить индикатор выполнения во время выполнения функций

    Математический модуль Python

    Python Scrapy: преобразование относительных путей в абсолютные пути

    Запуск Python неожиданно медленнее

    Python - лучший язык программирования в мире.