Python

2016-09-06 13 views
5

çıkmayacaktır programa asyncio iki asyncio görevlerle bir asyncio/Python program var: daha uzayıp gider Python

  • biri çöküyor

    • tane.

  • benim bütün program ilk kazadan sonra çıkmak istiyor. Bunun gerçekleşmesini sağlayamıyorum.

    import asyncio 
    import time 
    
    def infinite_while(): 
        while True: 
         time.sleep(1) 
    
    
    async def task_1(): 
        await asyncio.sleep(1) 
        assert False 
    
    
    async def task_2(): 
        loop = asyncio.get_event_loop() 
        await loop.run_in_executor(None, lambda: infinite_while()) 
    
    
    loop = asyncio.get_event_loop() 
    asyncio.set_event_loop(loop) 
    
    tasks = asyncio.gather(task_2(), task_1()) 
    try: 
        loop.run_until_complete(tasks) 
    except (Exception, KeyboardInterrupt) as e: 
        print('ERROR', str(e)) 
        exit() 
    

    O HATA yazdırır ama çıkış yok. elle kapalı olduğunda, program aşağıdaki yığın izleme yazdırır: İstisna bir görevde yükseldi

    Error in atexit._run_exitfuncs: 
    Traceback (most recent call last): 
        File "/usr/lib/python3.5/concurrent/futures/thread.py", line 39, in _python_exit 
        t.join() 
        File "/usr/lib/python3.5/threading.py", line 1054, in join 
        self._wait_for_tstate_lock() 
        File "/usr/lib/python3.5/threading.py", line 1070, in _wait_for_tstate_lock 
        elif lock.acquire(block, timeout): 
    KeyboardInterrupt 
    
    +2

    Eğer kooperatif çıkarken denediniz mi? Muhtemelen istediğin gibi değil, en azından bir deney olarak, şunları yapabilirsin: 'infinite_while' içindeki döngüyü 'exit_requested' olmasa bile değiştirebilirsin; savı istisnasını yakalamak, bayrağı ayarlamak ve yeniden yönlendirmek için 'task_1' değiştir; ve her bir görev çıktıktan sonra çıkış() öğesinin tamamlanıp tamamlanmadığını, onaylama istisnasıyla normal ve bir tane olup olmadığına bakın. –

    +0

    Teşekkürler, işe yarıyor, son çare olarak kullanacak ama onu çözmek için daha temiz bir yol olduğunu umuyoruz. – MrJ

    cevap

    1

    , bu yani loop.run_until_complete(tasks) çağrı görev eventloop aracılığıyla başlatılan kapsamında, yayar olmadı. istisna Görevinizdeki bağlamında sadece atılmış ve buna öyle idare şansına sahip üst düzey kapsamı sanki aksi takdirde "arka plan" arttı olacak, düşünün.

    try: 
        loop.run_until_complete(tasks) 
    except (Exception, KeyboardInterrupt) as e: 
        print('ERROR', str(e)) 
        exit() 
    

    ... ve bu sadece nasıl olay döngü çalışır geçerli:

    Bu Bununla görevden bir Exception yakalamak asla söyledi. Birkaç görevle bir hizmetiniz olup olmadığını düşünün ve bunlardan biri başarısız olur, bu da tüm hizmeti durduracaktır.

    Yapabilecekleriniz task1, örn.

    async def task_1(): 
        await asyncio.sleep(1) 
        try: 
         assert False 
        except Exception: 
         # get the eventloop reference somehow 
         eventloop.stop() 
    

    Ancak bu çok kirli ve tür hacky, bu yüzden oldukça daha temiz ve daha güvenli çözümü @D-Von suggested ile gitmek öneririz.

    +0

    Tam olarak bunu istediğim bir kullanım durumum var. Olay döngüsü eşzamanlılık ihtiyacım olan kodun küçük bir kısmı için başlatıldı ve durduruldu. Bir özel durum oluşursa, tüm olay döngüsünün durup durmamasını ve programın çıkmasını tercih ederim. Olay döngüsünde uzun süren çok çalışmam var, ancak süresiz olarak çalışan işlemlerim yok ve bir istisna olursa bunların hepsini iptal etmek istiyorum. Benim algıladığım şey, asyncio'nun eventloopun her zaman çalıştığı bir dünya için tasarlanmasıdır, fakat aynı zamanda farklı kullanım durumları için de iyi bir kütüphanedir. –