2016-12-31 6 views
1

次のコードは、asyncio.Queueオブジェクトをインスタンス化し、このキューを2つの異なるコルーチン(arrival()およびserver())から生成して消費しようとします。Python asyncioキューが更新されない

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)) 

原理は以下の通りである項目は、サーバーは無料でq

  • いつに追加され、

    • 1秒ごとに、それはキューに次のアイテムを取るか、それを待ち
    • サーバーは、期待される出力は次のようになり項目

    を処理するために1.8秒かかります。私は上記のコードが実行されることはありませんserver()while Trueループ内の要素を実行すると

    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 
    

    はしかし、q.qsize()は常に0であり、出力は次のようになります。

    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 
    ... 
    

    qオブジェクトがあると思われますarrival()によって更新されることはありません(q.qsize()は常に0です)。したがって、server()arrival()によって追加された項目に気づくことはありません。

  • 答えて

    2

    私はにあなたがそれを望むように、このランニングを得た:

    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) 
    

    残念ながら、私は申し訳ありません...私がしなければならなかったすべての変更を追跡しませんでした。しかし、私はあなたが違いを知っていると確信していると彼らはなぜ違いがあります。

    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

    ありがとう:

    が、これは出力を生成します!意味のあるビットは 'q.put(item)'の代わりに 'await q.put(item)'を呼んでいました。 'q.put'がコルーチンであるので理にかなっていますが、何とか私はそれを逃しました。 – Jivan

    +1

    @ジバンはい、これは私が変更したより重要なものの一つだったと付け加えたいと思っています...ごめんなさい。 & 明けましておめでとうございます! –

    +0

    一方、 'asyncio.gather()'を 'asyncio.wait()'に置き換えても、少なくともこの場合は何の効果もないようです。私はドキュメントの違いを調べる必要があります。明けましておめでとうございます! – Jivan

    関連する問題