2013-03-25 9 views
19

Po prostu zacząłem od python gevent i zastanawiałem się nad wykorzystaniem biblioteki cpu/mulitcore.Wykorzystanie wielordzeniowych Gevent

Próbując przykładów wykonujących wiele żądań za pośrednictwem monkeypatched urllib, zauważyłem, że działają one tylko na jednym rdzeniu przy 99% obciążeniu.

Jak mogę użyć wszystkich rdzeni z gevent za pomocą Pythona? Czy istnieje najlepsza praktyka? Czy są jakieś efekty uboczne przy użyciu wielu procesów i gevent?

BR dan

Odpowiedz

47

Gevent daje zdolność do radzenia sobie z wnioskami blokujących. Nie daje ci możliwości działania w trybie wielordzeniowym.

W danym czasie w procesie Pythona działa tylko jedna zielona (coroutine gevent). Prawdziwą zaletą geventu jest to, że jest bardzo potężny, gdy zajmuje się wąskimi gardłami wejścia/wyjścia (co zwykle ma miejsce w przypadku ogólnych aplikacji internetowych, aplikacji internetowych obsługujących punkty końcowe API, internetowych aplikacji do czatu lub zaplecza oraz, ogólnie, aplikacji sieciowych). Kiedy wykonujemy obliczenia ciężkie dla procesora, uzyskamy przyrost wydajności przy użyciu geventu. Gdy aplikacja jest związana we/wy, gevent jest czystą magią.

Jest jedna prosta zasada: Greenlets uzyskać przełączane z dala ilekroć I/O-operacja będzie blokować lub gdy robisz przełącznik jawnie (np gevent.sleep())

Wbudowany wątków Pythona faktycznie zachowywać się w tym samym (pseudo) "współbieżnym" sposobie, w jaki używa się zielonek Geventa.

Podstawowa różnica polega na tym, że w greenletach stosuje się wielozadaniowość kooperatywną, w której wątki wykorzystują multitasking wyprzedzający. Oznacza to, że greenlet nigdy nie przestanie wykonywać i "odda" do innej greenlet, chyba że używa pewnych funkcji "plonowania" (jak gevent.socket.socket.recv lub gevent.sleep).

Wątki z kolei przydadzą się innym wątkom (czasem nieprzewidywalnym) w zależności od tego, kiedy system operacyjny zdecyduje się je wymienić.

I wreszcie, do wykorzystania wielordzeniowych w Pythonie - jeśli tego właśnie chcesz - musimy polegać na module wieloprocesorowym (który jest wbudowanym modułem w Pythonie). To "dostaje GIL". Inne alternatywy obejmują używanie Jython lub wykonywanie zadań równolegle (na różnych procesorach) za pomocą kolejki zadań, np. Zeromq.

Napisałem tutaj bardzo długie wyjaśnienie - http://learn-gevent-socketio.readthedocs.org/en/latest/. Jeśli chcesz zanurkować w szczegółach. :-D

+2

Mogę dodać, że w zależności od przypadku, dobrym rozwiązaniem może być uruchomienie kilku procesów Pythona z geventami. Oczywiście nie jest to możliwe w przypadku, gdy procesy muszą komunikować się ze sobą w znaczącej ilości. – ferrix

+0

Dzięki za odpowiedź. Potrzebuję wykonać jak najwięcej operacji we/wy na komputerze. Pytanie brzmi: czy jestem w stanie wykonywać więcej żądań za pomocą n procesów (nie wątków), gdzie n = cpu_cores lub jest gevent z jednym procesem tak szybko, jak to możliwe? – thesonix

+1

Oto jak trunk.ly (według słów Alexa Dong'a) poradził sobie z problemem związanym z I/O związanym z przetwarzaniem ORAZ CPU (indeksują one witryny, a następnie umieszczają przeszukaną zawartość w indeksie wyszukiwania) - https://groups.google .com/d/msg/gevent/4hR1P6Vd-uk/4A4bw5ynuucJ –