2016-12-31 7 views
1

Der folgende Code instanziiert ein asyncio.Queue-Objekt und versucht, diese Warteschlange aus zwei verschiedenen Korotinen bzw. arrival() und server() aufzufüllen und zu konsumieren.Python asyncio queue nicht aktualisiert

loop = asyncio.get_event_loop() 
q = asyncio.Queue() 

async def arrival(q): 
    print('ARRIVAL - Queue id:', id(q)) 

    while True: 
     await asyncio.sleep(1) 
     item = random.choice(['item1', 'item2'..., 'item100']) 
     q.put(item) 

     print('ARRIVAL - added {}, qsize is now {}'.format(item, q.qsize())) 


async def server(q): 
    print('SERVER - Queue id:', id(q)) 

    while True: 
     item = await q.get() 
     print('SERVER - taking {}, qsize is now {}'.format(item, q.qsize())) 

     await asyncio.sleep(1.8) 
     print('SERVER - finished processing {}'.format(item)) 


tasks = [loop.create_task(arrival(q)), loop.create_task(server(q))] 
loop.run_until_complete(asyncio.gather(*tasks)) 

Das Prinzip ist das folgende:

  • alle 1 Sekunde, ein Element q
  • jederzeit hinzugefügt wird, der Server frei ist, nimmt es den nächsten Eintrag in der Warteschlange oder wartet auf ihn
  • Der Server nimmt 1,8 Sekunden ein Element

die erwartete Ausgabe würde zu verarbeiten:

SERVER - Queue id: 12345678 
ARRIVAL - Queue id: 12345678 
ARRIVAL - added item1, qsize is now 1 
SERVER - taking item1, qsize is now 0 
ARRIVAL - added item2, qsize is now 1 
SERVER - finished processing item1 
SERVER - taking item2, qsize is now 0 
ARRIVAL - added item3, qsize is now 1 
ARRIVAL - added item4, qsize is now 2 
SERVER - finished processing item2 
SERVER - taking item3, qsize is now 1 
ARRIVAL - added item5, qsize is now 2 
ARRIVAL - added item6, qsize is now 3 
SERVER - finished processing item3 
SERVER - taking item4, qsize is now 2 

Jedoch, wenn ich den obigen Code ausführen, werden die Elemente in while True Schleife in server() nie ausgeführt, ist q.qsize() immer 0, und der Ausgang ist:

SERVER - Queue id: 12345678 
ARRIVAL - Queue id: 12345678 
ARRIVAL - added item1, qsize is now 0 
ARRIVAL - added item2, qsize is now 0 
ARRIVAL - added item3, qsize is now 0 
ARRIVAL - added item4, qsize is now 0 
ARRIVAL - added item5, qsize is now 0 
... 

Es scheint, dass die q Objekt nie aktualisiert von arrival() (q.qsize() ist immer 0) und daher server() ist nie bewusst, die Elemente von arrival() hinzugefügt.

Antwort

2

Ich habe dies in der Art und Weise laufen Sie es wollen: ich hatte alle Änderungen vorzunehmen

import asyncio 
import random 

random.seed(31415) # get reproducible runs 

ITEMS = ['item{}'.format(i) for i in range(100)] 

async def arrival(q): 
    queue_object_id = id(q) 
    print('ARRIVAL - Queue id:', queue_object_id) 
    while True: 
     await asyncio.sleep(1) 
     item = random.choice(ITEMS) 
     await q.put(item) 
     size = q.qsize() 
     print('ARRIVAL - added {}, qsize is now {}'.format(item, size)) 

async def server(q): 
    queue_object_id = id(q) 
    print('SERVER - Queue id:', queue_object_id) 

    while True: 
     item = await q.get() 
     size = q.qsize() 
     print('SERVER - taking {}, qsize is now {}'.format(item, size)) 
     await asyncio.sleep(1.8) 
     print('SERVER - finished processing {}'.format(item)) 

loop = asyncio.get_event_loop() 
q = asyncio.Queue() 
cors = asyncio.wait([arrival(q), server(q)]) 
loop.run_until_complete(cors) 

leider habe ich nicht verfolgen ... sorry. Aber ich bin mir sicher, dass Sie die Unterschiede herausfinden und warum sie einen Unterschied machen.

dies erzeugt die Ausgabe:

SERVER - Queue id: 140540011741592 
ARRIVAL - Queue id: 140540011741592 
ARRIVAL - added item75, qsize is now 1 
SERVER - taking item75, qsize is now 0 
ARRIVAL - added item36, qsize is now 1 
SERVER - finished processing item75 
SERVER - taking item36, qsize is now 0 
ARRIVAL - added item57, qsize is now 1 
ARRIVAL - added item5, qsize is now 2 
SERVER - finished processing item36 
SERVER - taking item57, qsize is now 1 
ARRIVAL - added item69, qsize is now 2 
ARRIVAL - added item67, qsize is now 3 
SERVER - finished processing item57 
SERVER - taking item5, qsize is now 2 
ARRIVAL - added item53, qsize is now 3 
ARRIVAL - added item16, qsize is now 4 
SERVER - finished processing item5 
SERVER - taking item69, qsize is now 3 
ARRIVAL - added item91, qsize is now 4 
... 
+0

Dank! Das bedeutungsvolle Bit rief 'await q.put (item)' anstatt nur 'q.put (item)'. Macht Sinn, da 'q.put' eine Coroutine ist, aber irgendwie habe ich es verpasst. – Jivan

+1

@Jivan Ja, wollte hinzufügen, dass dies eines der wichtigeren Dinge war, die ich geändert habe ... Entschuldigung. & Frohes neues Jahr! –

+0

Andererseits scheint das Ersetzen von 'asyncio.gather()' durch 'asyncio.wait()' in diesem Fall keine Wirkung zu haben. Ich sollte den Unterschied in den Dokumenten untersuchen. Frohes neues Jahr! – Jivan