2017-02-17 8 views
0

Windowsマシンでasyncioでpyserialを使用しようとしています。Pyserialとasyncio

https://stackoverflow.com/a/27927704/1629704によってインパクトされた私のコードは、着信データ用のシリアルポートを常に見ています。

# This coroutine is added as a task to the event loop. 
@asyncio.coroutine 
def get_from_serial_port(self): 
    while 1: 
     serial_data = yield from self.get_byte_async() 
     <doing other stuff with serial_data> 

# The method which gets executed in the executor 
def get_byte(self): 
    data = self.s.read(1) 
    time.sleep(0.5) 
    tst = self.s.read(self.s.inWaiting()) 
    data += tst 
    return data 

# Runs blocking function in executor, yielding the result 
@asyncio.coroutine 
def get_byte_async(self): 
    with concurrent.futures.ThreadPoolExecutor(max_workers=1) as executor: 
     res = yield from self.loop.run_in_executor(executor, self.get_byte) 
     return res 

シリアルデータが返された後。コルーチンget_byte_asyncがwhileループ内で呼び出され、新しい実行プログラムが作成されます。私はいつも新しいスレッドを作成するのは高価だということを学んだので、別のアプローチをとるべきだと思っていますが、どうやってそれを行うのかは分かりません。 私はこの記事を読んでいますhttps://hackernoon.com/threaded-asynchronous-magic-and-how-to-wield-it-bba9ed602c32#.964j4a5s7

そして私は別のスレッドでシリアルポートの読書をする必要があると思います。しかし、シリアルデータを "メイン"ループに戻す方法はありますか?

答えて

0

デフォルトのエグゼキュータを使用してasyncio lockget_byteへのアクセスをロックすることができ、次のいずれか

async def get_byte_async(self): 
    async with self.lock: 
     return await self.loop.run_in_executor(None, self.get_byte) 

をそれとも単に一度、独自のexecutorを作成します。

async def get_byte_async(self): 
    if self.executor is None: 
     self.executor = concurrent.futures.ThreadPoolExecutor(max_workers=1) 
    return await self.loop.run_in_executor(self.executor, self.get_byte)