Es gibt Multiprozess-, Multithread- und nicht blockierende Methoden, um einen anderen Prozess auszuführen, bevor ein Prozess abgeschlossen ist. Ein Prozess ist eine Verarbeitungseinheit, die über einen eigenen Speicher verfügt, z. B. einen virtuellen Speicher, und der Speicher wird nicht von Prozessen gemeinsam genutzt. Da ein Thread eine Verarbeitungseinheit innerhalb eines Prozesses ist, teilen sich die Threads innerhalb desselben Prozesses den Speicher. Nicht blockierend kann auf mehrere Anfragen mit einem Thread antworten.
Es gibt zwei Kommunikationsmethoden für die Socket-Kommunikation: "Blockierende Kommunikation" und "Nicht blockierende Kommunikation". Das Blockieren ist eine Kommunikationsmethode, die auf den Abschluss des Sendens / Empfangens wartet und dann eine andere Verarbeitung startet. Daher wird sie häufig bei der sequentiellen Verarbeitung verwendet. Andererseits ist das Nichtblockieren eine Kommunikationsmethode, mit der eine andere Verarbeitung gestartet werden kann, auch wenn die Kommunikation nicht abgeschlossen ist. Daher wird sie häufig bei der Durchführung einer asynchronen Verarbeitung verwendet.
Ab Python 3.4 wurde der Standardbibliothek ein Modul namens "asyncio" hinzugefügt, um die nicht blockierende Verarbeitung zu ermöglichen (Referenz).
Über asyncio
ist es sehr leicht zu verstehen und in hier organisiert, und viele Beispiele werden veröffentlicht.
Ab uWSGI 1.9
wird der nicht blockierende Modus unterstützt, wie in [hier] beschrieben (http://uwsgi-docs.readthedocs.io/en/latest/Async.html).
Seit 2.0.4 wird auch "asyncio" unterstützt (Referenz).
Führen Sie unten in der Umgebung aus, in der Python 3.5 installiert ist.
greenlet
$ pip3 install greenlet
greenlet
installiert ist.$ find / -name greenlet -type d
In der Umgebung von "Mac OS" war das Ergebnis "/ Users / xxx / .pyenv / version / 3.5.0 / include / python3.5m / greenlet". Führen Sie daher Folgendes aus.
$ CFLAGS="-I/Users/xxx/.pyenv/versions/3.5.0/include/python3.5m" UWSGI_PROFILE="asyncio" pip3 install uwsgi
Führen Sie eine einfache Überprüfung des Betriebs mit Blockierung und Nichtblockierung durch. Im Beispielcode wird die Datei gelesen, für diese Datei wird jedoch Folgendes verwendet.
numbers.txt
zero
one
two
three
four
five
Bei der Überprüfung wurde auch Apache Bench
verwendet, aber bei Verwendung von local [hier](https://stackoverflow.com/questions/7938869/ab-is-erroring-out-with-apr-socket- Es ist notwendig, vorsichtig zu sein, wie in recv-connection-verweigert-61) beschrieben, und diesmal wird es mit dem folgenden Befehl ausgeführt.
$ ab -n 10000 -c 100 http://127.0.0.1:9090/
$ pip3 unistall uwsgi
Protokollieren Sie den Inhalt der gelesenen Datei.
def application(environ, start_response):
def my_generator(name):
with open(name) as lines:
yield from lines
g = my_generator("numbers.txt")
for k, v in enumerate(g):
print("%s:%s" % (k, v), end="")
start_response('200 OK', [('Content-Type','text/html')])
return [b"Hello World"]
Führen Sie die Ausführung mit der Anzahl der Prozesse und Threads aus, die als 1 angegeben sind.
$ uwsgi --http-socket :9090 --processes 1 --threads 1 --logto uwsgi.log --wsgi-file webapp.py
Ergebnisse von "Apache Bench" (nur einige).
Requests per second: 2694.06 [#/sec](mean)
Time per request: 37.119 [ms](mean)
Time per request: 0.371 [ms](mean, across all concurrent requests)
Transfer rate: 144.70 [Kbytes/sec] received
Protokollausgabe des Inhalts der Datei, die nach 5 Sekunden asynchron gelesen wird.
import asyncio
@asyncio.coroutine
def my_generator(name):
with open(name) as lines:
yield from lines
def read():
g = my_generator("numbers.txt")
for k, v in enumerate(g):
print("%s:%s" % (k, v), end="")
def application(environ, start_response):
asyncio.get_event_loop().call_later(5, read)
start_response('200 OK', [('Content-Type','text/html')])
return [b"Hello World"]
Führen Sie dies aus, indem Sie 1 für die Anzahl der Prozesse und Threads angeben, wie im Fall des Blockierens.
$ uwsgi --asyncio 2 --http-socket :9090 --greenlet --processes 1 --threads 1 --logto uwsgi.log --wsgi-file webapp.py
Hier wird "2" für "--asyncio" angegeben, aber wenn es auf "1" gesetzt ist, wird Folgendes angezeigt und es startet nicht.
the greenlet suspend engine requires async mode
Wenn Sie in den "asynchronen Modus" schauen, wie unten beschrieben, gibt es eine Speicherstruktur, die als Kern bezeichnet wird und Daten für jede Anforderung speichert (definiert als Kern, da das Konzept der Threads verwirrend ist).
Technically, cores are simple memory structures holding request’s data, but to give the user
the illusion of a multithreaded system we use that term.
Diese Kerne müssen ausgetauscht werden, und es sind wahrscheinlich nur zwei oder mehr.
Each core can manage a single request, so the more core you spawn, more requests you will be
able to manage (and more memory you will use). The job of the suspend/resume engines is to stop
the current request management, move to another core, and eventually come back to the old one
(and so on).
Im Vergleich zum Blockieren ist dieses Beispiel in Bezug auf die Leistung etwas langsamer. Es scheint besser, mit anderen Proben zu vergleichen.
equests per second: 2336.16 [#/sec](mean)
Time per request: 42.805 [ms](mean)
Time per request: 0.428 [ms](mean, across all concurrent requests)
Transfer rate: 125.48 [Kbytes/sec] received
Da ich 2 Kerne im nicht blockierenden Modus verwende, habe ich "uWSGI" neu installiert und die Anzahl der Threads mit 2 überprüft. Das Ergebnis ist unten. Möglicherweise liegt ein Problem mit der Mac-Umgebung vor.
Requests per second: 2691.94 [#/sec](mean)
Time per request: 37.148 [ms](mean)
Time per request: 0.371 [ms](mean, across all concurrent requests)
Transfer rate: 144.59 [Kbytes/sec] received
Ich möchte "Asyncio" etwas genauer studieren, ein Framework wie "Flask" einführen und die Überprüfung fortsetzen, die unter bestimmten Bedingungen wie der Verwendung von Nginx auch als Forschung dient. Probieren Sie auch andere Sprachen aus, z. B. den Vergleich mit Golang.
Hier sagt "Wenn Sie Zweifel haben, verwenden Sie nicht den Async-Modus.", Aber es ist immer noch auf einem praktischen Niveau. Ist es einfach nicht erreicht? Oder haben Sie den richtigen Weg dazu?
Recommended Posts