2015-04-06 23 views
8

Bir eşyordamın için stdin'den bir veri geçirerek basit bir fikri uygulamaya çalışıyorum: Bu kod, bir değişkenle İşin inceliği, ancak basitleştirilmiş bir sürümünü çalışırPython asyncio: okuyucu geri arama ve eşyordam iletişimin

import asyncio 
import sys 

event = asyncio.Event() 

def handle_stdin(): 
    data = sys.stdin.readline() 
    event.data = data # NOTE: data assigned to the event object 
    event.set() 

@asyncio.coroutine 
def tick(): 
    while 1: 
     print('Tick') 
     yield from asyncio.sleep(1) 

     if event.is_set(): 
      data = event.data # NOTE: data read from the event object 
      print('Data received: {}'.format(data)) 
      event.clear() 

def main(): 
    loop = asyncio.get_event_loop() 
    loop.add_reader(sys.stdin, handle_stdin) 
    loop.run_until_complete(tick())  

if __name__ == '__main__': 
    main() 

yerine Event nesnenin çok çalışır:

data = None 

def handle_stdin(): 
    global data 
    data = sys.stdin.readline() 

@asyncio.coroutine 
def tick(): 
    while 1: 
     print('Tick') 
     yield from asyncio.sleep(1) 

     global data 
     if data is not None: 
      print('Data received: {}'.format(data)) 
      data = None 

Benim sorulara

şunlardır: Event ile yaklaşım doğru mu? Ya da bu tür bir sorunu çözmek için başka bir asyncio nesnesiyle daha iyi bir yol var mı? Event ile yaklaşım gayet eğer Sonra, bir değişken kullanılarak de gayet iyi olduğunu?

Teşekkür ederiz.

cevap

12

çok daha uygun üretici/tüketici ilişkisinin bu tür içindir ve sleep, uyandırma, kontrol etme, uykuya geri dönme, döngü, global değişkenle benzer. Böylece Queue yaklaşımı daha basit, daha küçüktür ve olay döngüsünü diğer olası çözümlerden daha az engeller. Diğer çözümler ki onlar (sürece herhangi yield from aramaları içeride eğer if event.is_set() ve if data is not None: blok tanıtmak yok gibi) düzgün olacak, teknik doğrudur. Onlar sadece biraz tıkalı. event.wait gelen

+0

Çok teşekkürler @dano, 'queue' yaklaşımı' 'olay '' birinden gerçekten daha iyi görünüyor. –

2

Bir etkinlik için beklemek isterseniz, is_set numaralı oylama yerine Event.wait kullanıyor olmanız gerekir. Düzgün tanımsız/ayarladığınız emin olmak gerekir bir Event ile daha ilgili daha az mantık var

import asyncio 
import sys 

queue = asyncio.Queue() 

def handle_stdin(): 
    data = sys.stdin.readline() 
    asyncio.async(queue.put(data)) # Queue.put is a coroutine, so you can't call it directly. 

@asyncio.coroutine 
def tick(): 
    while 1: 
     data = yield from queue.get() 
     print('Data received: {}'.format(data)) 

def main(): 
    loop = asyncio.get_event_loop() 
    loop.add_reader(sys.stdin, handle_stdin) 
    loop.run_until_complete(tick())  

if __name__ == '__main__': 
    main() 

var: Ben asyncio.Queue düşünüyorum

@asyncio.coroutine 
def tick(): 
    while True: 
     yield from event.wait() 
     print('Data received: {}'.format(event.data)) 
     event.clear() 
+0

Doğru, aslında daha basit 'verim() 'döngü olmadan yeterli olmalıdır. –