(Dawno temu) napisałem pająka sieciowego, który wielowątkowo, aby umożliwić jednoczesne występowanie w tym samym czasie. Tak było w mojej młodości w Pythonie, w czasach, kiedy wiedziałem o GIL i związanych z nim nieszczęściach dla wielowątkowego kodu (IE, w większości przypadków rzeczy są po prostu serializowane!) ...
Chciałbym przerobić ten kod, aby był bardziej niezawodny i działał lepiej. Są w zasadzie dwa sposoby, aby to zrobić: mógłbym użyć nowego modułu wieloprocesowego w wersji 2.6+ lub wybrać jakiś model oparty na reaktorze / zdarzeniu. Wolę zrobić później, ponieważ jest to o wiele prostsze i mniej podatne na błędy.
Pytanie dotyczy więc tego, jakie ramy najlepiej pasowałyby do moich potrzeb. Poniżej znajduje się lista znanych mi opcji:
- Twisted : Dziadek struktur reaktorów Pythona: wydaje się złożony i nieco rozdęty. Stroma krzywa uczenia się dla małego zadania.
- Eventlet : Od facetów z Lindenlab . Ramy oparte na Greenlet ukierunkowane na tego rodzaju zadania. Spojrzałem jednak na kod i nie jest zbyt ładny: niezgodny z Pep8, rozrzucony wydrukami (dlaczego ludzie robią to w ramach !?), API wydaje się trochę niespójne.
- PyEv : Niedojrzały, nie wydaje się, żeby ktoś go teraz używał, chociaż jest oparty na libevent, więc ma solidny backend.
- asyncore : Z poziomu niskiego poziomu stdlib: über, wydaje się, że dużo pracy nóg wymaga tylko zrobienia czegoś z ziemi.
- tornado : Chociaż jest to produkt zorientowany na serwer, przeznaczony do dynamicznych serwerów internetowych, zawiera on asynchronicznego klienta HTTP i prosty ioloop . Wygląda na to, że może to zrobić zadanie, ale nie do tego, do czego było przeznaczone. [edytuj: niestety nie działa w systemie Windows, co dla mnie się liczy - jest to wymagane, aby obsługiwać tę kiepską platformę]
Czy w ogóle coś mi umknęło? Z pewnością musi istnieć biblioteka, która pasuje do najprostszej biblioteki uproszczonej sieci asynchronicznej!
[edytuj: wielkie podziękowania dla intgr za jego wskaźnik do tej strony . Jeśli przewiniesz do dołu, zobaczysz naprawdę fajną listę projektów, które mają na celu sprostanie temu zadaniu w taki czy inny sposób. Wydaje się, że w rzeczywistości rzeczy potoczyły się od momentu powstania Twisted: ludzie wydają się teraz preferować rozwiązanie oparte na wspólnej procedurze , a nie tradycyjne rozwiązanie zorientowane na reaktor / oddzwanianie. Korzyści z tego podejścia są wyraźniejsze, bardziej bezpośredni kod: z pewnością znalazłem w przeszłości, szczególnie podczas pracy z boost.asiow C ++ ten kod oparty na wywołaniu zwrotnym może prowadzić do projektów trudnych do naśladowania i stosunkowo mało widocznych dla niewprawnego oka. Korzystanie z procedur wspólnych pozwala pisać kod, który wygląda trochę bardziej synchronicznie. Wydaje mi się, że teraz moim zadaniem jest ustalenie, której z tych wielu bibliotek lubię wyglądać i spróbować! Cieszę się, że zapytałem teraz ...]
[edytuj: być może zainteresuje każdego, kto podążył za tym pytaniem lub natknął się na to pytanie lub w jakikolwiek sposób troszczy się o ten temat: Znalazłem naprawdę świetny opis aktualnego stanu dostępnych narzędzi do tego zadania]
select
do multipleksowania I / O. Ale powinieneś być w stanie uzyskać z tego przyzwoitą wydajność dzięki tornado-pyuv . 2. Istnieje obecnie asyncio w Pythonie 3.3+ i jego backportu trollius który pozwala uruchomić dowolną aplikację Tornado w pętli zdarzeń (Twisted wspierane będą wkrótce).Odpowiedzi:
Podobał mi się moduł współbieżności Pythona, który wykorzystuje zarówno bezprogowe mikroprzerwy Pythona, albo Greenlety do lekkiego gwintowania. Wszystkie blokujące sieciowe we / wy są w sposób przejrzysty asynchroniczne za pośrednictwem pojedynczej
libevent
pętli, więc powinny być niemal tak samo wydajne jak prawdziwy serwer asynchroniczny.Podejrzewam, że w ten sposób jest podobny do Eventletu.
Minusem jest to, że jego interfejs API jest zupełnie inny niż Python
sockets
/threading
moduły; musisz przepisać sporo aplikacji (lub napisać warstwę podkładki kompatybilności)Edycja: Wygląda na to, że istnieje również cogen , który jest podobny, ale używa ulepszonych generatorów Python 2.5 dla swoich korpusów, zamiast Greenletów. To sprawia, że jest bardziej przenośny niż współbieżność i inne alternatywy. Network I / O odbywa się bezpośrednio za pomocą epoll / kqueue / iocp.
źródło
Twisted jest skomplikowane, masz rację. Twisted nie jest wzdęty.
Jeśli spojrzysz tutaj: http://twistedmatrix.com/trac/browser/trunk/twisted znajdziesz zorganizowany, wszechstronny i bardzo dobrze przetestowany pakiet wielu protokołów internetowych, a także kod pomocniczy do napisania i wdrażaj bardzo wyrafinowane aplikacje sieciowe. Nie pomyliłbym wzdęcia z kompleksowością.
Powszechnie wiadomo, że dokumentacja Twisted na pierwszy rzut oka nie jest najbardziej przyjazna dla użytkownika i uważam, że odwraca to uwagę niefortunnej liczby osób. Ale Twisted jest niesamowity (IMHO), jeśli poświęcisz czas. Zrobiłem i okazało się, że było warto, i poleciłbym innym, aby spróbowali tego samego.
źródło
gevent jest oczyszczony z eventletów .
Pod względem interfejsu API jest zgodny z tymi samymi konwencjami, co standardowa biblioteka (w szczególności moduły wątków i wieloprocesowe), jeśli ma to sens. Masz więc znane rzeczy, takie jak Kolejka i Zdarzenie, z którymi możesz pracować.
Obsługuje tylko libevent ( aktualizacja: libev od wersji 1.0 ) jako implementację reaktora, ale w pełni go wykorzystuje, oferując szybki serwer WSGI oparty na libevent-http i rozwiązujący zapytania DNS za pośrednictwem libevent-dns, w przeciwieństwie do korzystania z puli wątków, jak większość innych bibliotek robić. ( aktualizacja: ponieważ 1,0 cresy są używane do asynchronicznego zapytania DNS; pula wątków jest również opcją).
Podobnie jak eventlet, sprawia, że wywołania zwrotne i odroczenia nie są konieczne przy użyciu greenletów .
Sprawdź przykłady: jednoczesne pobieranie wielu adresów URL , długi czat sieciowy z odpytywaniem .
źródło
Naprawdę interesujące porównanie takich ram opracował Nicholas Piël na swoim blogu: warto je przeczytać!
źródło
Żadne z tych rozwiązań nie pozwoli uniknąć faktu, że GIL zapobiega równoległości procesora - to po prostu lepsze sposoby uzyskania równoległości we / wy, które już masz z wątkami. Jeśli uważasz, że możesz zrobić lepiej we / wy, wykonaj wszystkie te czynności, ale jeśli masz wąskie gardło w przetwarzaniu wyników, nic tutaj nie pomoże, oprócz modułu wieloprocesowego.
źródło
Nie posunąłbym się nawet do nazwania Twisted wzdęcia, ale trudno jest owinąć głowę. Dość długo unikałem uczenia się, ponieważ zawsze chciałem czegoś łatwiejszego do „małych zadań”.
Jednak teraz, gdy trochę z tym pracowałem, muszę powiedzieć, że posiadanie wszystkich dołączonych baterii jest BARDZO miłe.
Wszystkie inne biblioteki asynchroniczne, nad którymi pracowałem, są o wiele mniej dojrzałe, niż się nawet wydaje. Pętla zdarzeń Twisted jest solidna.
Nie jestem do końca pewien, jak rozwiązać stromą krzywą uczenia się Twisted. Może to pomóc, jeśli ktoś rozwidli go i wyczyści kilka rzeczy, takich jak usunięcie wszystkich cruft kompatybilności wstecznej i martwych projektów. Ale taka jest natura dojrzałego oprogramowania.
źródło
PortableGtkReactor
?Kamaelia nie została jeszcze wspomniana. Jego model współbieżności opiera się na łączeniu ze sobą komponentów z przekazywaniem wiadomości między skrzynkami odbiorczymi i skrzynkami odbiorczymi. Oto krótki przegląd.
źródło
Zacząłem używać skręconych do niektórych rzeczy. Piękno tego jest prawie dlatego, że jest „wzdęte”. Istnieją złącza dla niemal wszystkich głównych protokołów. Możesz mieć bot Jabbera, który będzie przyjmował polecenia i publikował je na serwerze IRC, wysyłał je do kogoś pocztą e-mail, uruchamiał polecenie, czytał z serwera NNTP i monitorował stronę internetową pod kątem zmian. Zła wiadomość jest taka, że może to wszystko zrobić i może sprawić, że będzie to zbyt skomplikowane w przypadku prostych zadań, takich jak wyjaśnienie PO. Zaletą Pythona jest to, że dołączasz tylko to, czego potrzebujesz. Więc chociaż pobieranie może wynosić 20 MB, możesz dołączyć tylko 2 MB bibliotek (co wciąż jest dużo). Moja największa skarga na twisted polega na tym, że obejmują one przykłady, wszystko poza podstawowym serwerem tcp, na który jesteś sam.
Chociaż nie jest to rozwiązanie python, widziałem, że node.js zyskuje ostatnio znacznie większą przyczepność. Właściwie zastanawiałem się, czy nie przyjrzeć się mniejszym projektom, ale wzdrygam się, gdy słyszę javascript :)
źródło
Jest dobra książka na ten temat: „Twisted Network Programming Essentials” Abe Fettiga. Przykłady pokazują, jak pisać bardzo Pythoniczny kod, a dla mnie osobiście nie wydaje mi się, że jest oparty na rozdętym frameworku. Spójrz na rozwiązania w książce, jeśli nie są czyste, to nie wiem, co oznacza czyste.
Moja jedyna zagadka jest taka sama, jak w przypadku innych frameworków, takich jak Ruby. Martwię się, czy to się powiększa? Nie chciałbym angażować klienta w środowisko, które będzie miało problemy ze skalowalnością.
źródło
Whizzer to mała struktura gniazd asynchronicznych, która wykorzystuje pyev. Jest bardzo szybki, głównie z powodu pyev. Stara się zapewnić podobny interfejs, z niewielkimi zmianami.
źródło
Spróbuj także Syncless . Jest oparty na coroutine (więc jest podobny do Concurrence, Eventlet i gevent). Implementuje nie-blokujące zamienniki dla socket.socket, socket.gethostbyname (itp.), Ssl.SSLSocket, time.sleep i select.select. To jest szybkie. Potrzebuje Stackless Python i libevent. Zawiera obowiązkowe rozszerzenie napisane w języku C (Pyrex / Cython).
źródło
Potwierdzam dobroć synchronizacji . Może korzystać z libev (nowszej, czystszej i lepszej wersji libevent). Czasami nie ma tak dużego wsparcia jak libevent, ale teraz proces rozwoju idzie dalej i jest bardzo przydatny.
źródło
Jeśli chcesz tylko uproszczoną, lekką bibliotekę żądań HTTP, uważam, że Unirest jest naprawdę dobry
źródło
Zapraszamy do zapoznania się z PyWorks, który ma zupełnie inne podejście. Pozwala instancjom obiektowym na działanie we własnym wątku i sprawia, że wywołania funkcji dla tego obiektu są asynchroniczne.
Po prostu pozwól klasie dziedziczyć po zadaniu zamiast obiektu i jest asynchroniczna, wszystkie wywołania metod są proxy. Zwracane wartości (jeśli ich potrzebujesz) są przyszłymi serwerami proxy.
PyWorks można znaleźć na stronie http://bitbucket.org/raindog/pyworks
źródło