2016-04-24 4 views
0

, ich versuche nur, meinen Kopf um Asynchron-Programmierung zu wickeln (insbesondere der Tornado-Framework), und dachte, ich würde mit den Grundlagen beginnen: Aufruf „wartet“ auf zwei Koroutinen:Warum werden zwei sequentielle Coroutinen (Async-Funktionen) nicht parallel ausgeführt? So

from tornado.ioloop import IOLoop 
from tornado.web import Application, url, RequestHandler 
from tornado.gen import sleep 

class TestHandler(RequestHandler):  
    async def get(self): 
     f1 = await self.test("f1") 
     f2 = await self.test("f2") 
     self.write(f1 + " " + f2) 

    async def test(self, msg): 
     for i in range(5): 
      print(i) 
      await sleep(1) # this is tornado's async sleep 
     return msg 

app = Application([url(r'/', TestHandler)], debug=True) 
app.listen(8080) 
ioloop = IOLoop.current() 
ioloop.start() 

Die Problem ist jedoch, dass, wenn ich localhost:8080 getroffen in meinem Browser, und starre auf meiner python-Konsole, sehe ich nicht zwei miteinander verwobenen Sequenzen von 0 1 2 3 4, sondern zwei aufeinanderfolgende Sequenzen ...

ich den Tornado FAQ gelesen habe wieder und wieder und kann nicht verstehen, was ich falsch mache.

Antwort

2

Dies läuft f1, wartet es dann zu beenden, f2 läuft:

f1 = await self.test("f1") 
    f2 = await self.test("f2") 

Um die Dinge parallel zu laufen, kann man nicht await der erste vor dem zweiten beginnen. Der einfachste Weg, dies zu tun ist, sie beide in einer await zu tun:

f1, f2 = await tornado.gen.multi(self.test("f1"), self.test("f2")) 

Oder in fortgeschrittenen Fällen Sie f1 ohne zu warten, beginnen für sie dann zurück kommen später darauf warten:

f1_future = tornado.gen.convert_yielded(self.test("f1")) 
f2_future = tornado.gen.convert_yielded(self.test("f2")) 
f1 = await f1_future 
f2 = await f2_future 
+0

Der zweite Codeblock (mit den erwarteten Futures) läuft nicht parallel ... Missverstehe ich dich und es sollte nicht erwartet werden? – StevieP

+0

Ah, du hast Recht. Dieses Muster funktionierte mit '@ gen.coroutine', aber' async def'-Funktionen starten erst, wenn sie von etwas "erwartet" werden. –

+0

Würde es Ihnen etwas ausmachen, Best Practices zu erklären? Es scheint, dass Tornado und 'asyncio' (insbesondere' async'/'erwarten') nicht wirklich gut zusammenspielen. Wie sollen wir asynchronen Code schreiben/dekorieren (wenn wir Tornado verwenden wollen)? – StevieP

Verwandte Themen