Heim  >  Artikel  >  Backend-Entwicklung  >  Detaillierte Erläuterung der Verwendung von Tornado-Coroutinen in Python (mit Beispielen)

Detaillierte Erläuterung der Verwendung von Tornado-Coroutinen in Python (mit Beispielen)

不言
不言nach vorne
2018-10-16 16:03:533903Durchsuche
Dieser Artikel bietet Ihnen eine detaillierte Erklärung der Verwendung von Tornado-Coroutinen in Python (mit Beispielen). Ich hoffe, dass er für Freunde hilfreich ist.

Durch die Verwendung von Tornado-Coroutinen kann ein asynchrones Verhalten entwickelt werden, das dem synchronen Code ähnelt. Da die Coroutine selbst keine Threads verwendet, verringert sie gleichzeitig den Aufwand für den Thread-Kontextwechsel und ist ein effizientes Entwicklungsmodell.

1. Coroutine-Funktion schreiben

Beispiel: Verwendung der Coroutine-Technologie zur Entwicklung einer Webseitenzugriffsfunktion

#用协程技术开发网页访问功能
from tornado import  gen #引入协程库gen
from tornado.httpclient import AsyncHTTPClient
import time

#使用gen.coroutine修饰器
@gen.coroutine
def coroutine_visit():
    http_client=AsyncHTTPClient()
    response=yield http_client.fetch("http://www.baidu.com")
    print(response.body)

In diesem Beispiel wird weiterhin der asynchrone Client AsyncHTTPClient für den Seitenzugriff verwendet. Der Dekorator @gen.coroutine erklärt, dass es sich um eine Coroutine-Funktion handelt. Aufgrund des yield-Schlüsselworts ist es nicht erforderlich, eine Callback-Funktion in den Code zu schreiben, um die Zugriffsergebnisse zu verarbeiten. Stattdessen kann die Ergebnisverarbeitungsanweisung direkt nach geschrieben werden Ertragserklärung.

2. Rufen Sie die Coroutine-Funktion auf

Da die Tornado-Coroutine auf der Grundlage des Python-Schlüsselworts yield implementiert wird, kann sie nicht direkt wie eine gewöhnliche Funktion aufgerufen werden.
Coroutine-Funktionen können auf die folgenden drei Arten aufgerufen werden:

  • Wird über das Schlüsselwort yield innerhalb einer Funktion aufgerufen, die selbst eine Coroutine ist.

  • Wenn IOLoop nicht gestartet ist, wird es über die Funktion run_sync() von IOLoop aufgerufen.

  • Wenn IOLoop gestartet wurde, wird es über die Funktion spawn_callback() von IOLoop aufgerufen.

Beispiel: Aufruf der Coroutine-Funktion über die Coroutine-Funktion

Code:

#用协程技术开发网页访问功能
from tornado import  gen #引入协程库gen
from tornado.httpclient import AsyncHTTPClient
import time

#使用gen.coroutine修饰器
@gen.coroutine
def coroutine_visit():
    http_client=AsyncHTTPClient()
    response=yield http_client.fetch("http://www.baidu.com")
    print(response.body)

@gen.coroutine
def outer_coroutine():
    print("start call coroutine_visit")
    yield coroutine_visit()
    print("end call coroutine_cisit")

In diesem Beispiel sind äußere_coroutine() und coroutine_visit() beides Coroutine-Funktionen Programmierfunktionen, sodass sie über das Schlüsselwort yield aufgerufen werden können. _

Beispiel: Wenn IOLoo nicht gestartet wurde, wird es über die Funktion run_sync() von IOLoop aufgerufen.
IOLoop ist das Hauptereignisschleifenobjekt von Tornado. Das Tornado-Programm verwendet es, um Zugriffsanfragen von externen Clients zu überwachen und entsprechende Vorgänge auszuführen.

Code:

#用协程技术开发网页访问功能
from tornado import  gen #引入协程库gen
from tornado.httpclient import AsyncHTTPClient
from tornado.ioloop import IOLoop  #引入IOLoop对象

#使用gen.coroutine修饰器
@gen.coroutine
def coroutine_visit():
    http_client=AsyncHTTPClient()
    response=yield http_client.fetch("http://www.baidu.com")
    print(response.body)

def func_normal():
    print("start call coroutine_visit")
    IOLoop.current().run_sync(lambda :coroutine_visit())
    print("end call coroutine_visit")
Wenn das Programm nicht in den laufenden Zustand von IOLoop eingetreten ist, kann die Coroutine-Funktion über die Funktion run_sync() aufgerufen werden.

Hinweis: Die Funktion run_sync() blockiert den Aufruf der aktuellen Funktion, bis die aufgerufene Coroutine ausgeführt wird.

Tatsächlich erfordert Tornado, dass die Coroutine-Funktion im laufenden Zustand von IOLoop aufgerufen werden kann, aber die Funktion run_sync führt die Schritte zum Starten und Stoppen von IOLoop automatisch aus:

[IOLoop starten]》[Die von Lambda gekapselte Coroutine-Funktion aufrufen]》[IOLoop stoppen]

Beispiel: Wenn IOLoop gestartet wird, rufen Sie
Code:

#用协程技术开发网页访问功能
from tornado import  gen #引入协程库gen
from tornado.httpclient import AsyncHTTPClient
from tornado.ioloop import IOLoop  #引入IOLoop对象

#使用gen.coroutine修饰器
@gen.coroutine
def coroutine_visit():
    http_client=AsyncHTTPClient()
    response=yield http_client.fetch("http://www.baidu.com")
    print(response.body)

def func_normal():
    print("start call coroutine_visit")
    IOLoop.current().spawn_callback(coroutine_visit)
    print("end call coroutine_visit")
Die Funktion spawn_callback() wartet nicht darauf, dass die aufgerufene Coroutine die Ausführung abschließt. Alle oberen und unteren Druckanweisungen werden sofort abgeschlossen und coroutine__visit selbst wird zum entsprechenden Zeitpunkt von IOLoop aufgerufen .

Hinweis: Die spawn_callback()-Funktion von IOLoop stellt Entwicklern keine Methode zum Erhalten des Rückgabewerts eines Coroutine-Funktionsaufrufs zur Verfügung, sodass Sie span_callback() nur zum Aufrufen einer Coroutine-Funktion ohne Rückgabewert verwenden können.

3. Blockierungsfunktionen in Coroutinen aufrufen

Der direkte Aufruf von Blockierungsfunktionen in Coroutinen wirkt sich auf die Leistung der Coroutinen selbst aus. Daher bietet Tornado die Verwendung von Thread-Pools zum Planen von Blockierungsfunktionen in Coroutinen an hat keinen Einfluss auf die weitere Ausführung der Coroutine selbst.

Codebeispiel:

from concurrent.futures import ThreadPoolExecutor
from tornado import gen

#定义线程池
thread_pool=ThreadPoolExecutor(2)

def mySleep(count):
    import time
    for x in range(count):
        time.sleep(1)

@gen.coroutine
def call_blocking():
    print("start")
    yield thread_pool.submit(mySleep,10)
    print("end")
Der Code referenziert zunächst die ThreadPoolExecutor-Klasse von concurrent.futures und instanziiert einen Thread-Pool thread_pool, der aus zwei Threads besteht. Verwenden Sie in der Coroutine call_blocking, die eine Blockierungsfunktion aufrufen muss, thread_pool.submit, um die Blockierungsfunktion aufzurufen und über yield zurückzugeben. Dies blockiert nicht die weitere Ausführung des Threads, in dem sich die Coroutine befindet, und stellt außerdem die Ausführungsreihenfolge des Codes vor und nach der Blockierungsfunktion sicher.

4. Warten auf mehrere asynchrone Aufrufe in der Coroutine

Bisher kennen wir die Programmiermethode des Wartens auf einen asynchronen Aufruf mit dem Schlüsselwort yield in der Coroutine. Tatsächlich ermöglicht Tornado die Verwendung eines Yield-Schlüsselworts in einer Coroutine, um auf mehrere asynchrone Aufrufe zu warten. Sie müssen diese Aufrufe nur in Form einer Liste oder eines Wörterbuchs an das Yield-Schlüsselwort übergeben.

Beispiel: Verwenden Sie eine Liste, um mehrere asynchrone Aufrufe zu übergeben
#使用列表方式传递多个异步调用
from tornado import gen  #引入协程库gen
from tornado.httpclient import AsyncHTTPClient

@gen.coroutine   #使用gen.coroutine修饰器
def coroutine_visit():
    http_client=AsyncHTTPClient()
    list_response=yield [
        http_client.fetch("http://www.baidu.com"),
        http_client.fetch("http://www.api.jiutouxiang.com")
    ]
    for response in list_response:
        print(response.body)
Verwenden Sie weiterhin den @gen.coroutine-Dekorator, um die Coroutine im Code zu definieren, und verwenden Sie eine Liste, um eine Zahl zu übergeben wobei yield erforderlich ist. Bei einem asynchronen Aufruf kehrt yield erst dann zurück und setzt die Ausführung fort, wenn alle Aufrufe in der Liste abgeschlossen sind. yield gibt die Anrufergebnisse in einer Liste zurück.

Beispiel: Übergeben Sie mehrere asynchrone Aufrufe im Wörterbuchmodus:
#使用列表方式传递多个异步调用
from tornado import gen  #引入协程库gen
from tornado.httpclient import AsyncHTTPClient

@gen.coroutine   #使用gen.coroutine修饰器
def coroutine_visit():
    http_client=AsyncHTTPClient()
    dict_response=yield {
       "baidu": http_client.fetch("http://www.baidu.com"),
        "9siliao":http_client.fetch("http://www.api.jiutouxiang.com")
    }
    print(dict_response["baidu"].body)

Das obige ist der detaillierte Inhalt vonDetaillierte Erläuterung der Verwendung von Tornado-Coroutinen in Python (mit Beispielen). Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:segmentfault.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen