Question on asyncio

Marko Rauhamaa marko at pacujo.net
Sun Feb 22 16:21:42 EST 2015


pfranken85 at gmail.com:

> I have some functions which are reading values from hardware. If one
> of the values changes, I want a corresponding notification to the
> connected clients. The network part shouldn't be the problem. Here is
> what I got so far:
>
> @asyncio.coroutine
> def check():
>   old_val = read_value_from_device()
>   yield from asyncio.sleep(2)
>   new_val = read_value_from_device()
>   # we may have fluctuations, so we introduce a threshold
>   if abs(new_val-old_val) > 0.05:
>       return new_val
>   else:
>       return None
>       
> @asyncio.coroutine
> def runner():
>   while 1:
>     new = yield from check()
>     print(new)

In asyncio, you typically ignore the value returned by yield. While
generators use yield to communicate results to the calling program,
coroutines use yield only as a "trick" to implement cooperative
multitasking and an illusion of multithreading.

Thus, "yield from" in asyncio should be read, "this is a blocking
state."

> Is this the way one would accomplish this task? Or are there better
> ways? Should read_value_from_device() be a @coroutine as well? It may
> contain parts that take a while ... Of course, instead of print(new) I
> would add the corresponding calls for notifying the client about the
> update.

How do you read a value from the hardware? Do you use a C extension? Do
you want read_value_from_device() to block until the hardware has the
value available or is the value always available for instantaneous
reading?

If the value is available instantaneously, you don't need to turn it
into a coroutine. However, if blocking is involved, you definitely
should do that. Depending on your hardware API it can be easy or
difficult. If you are running CPython over linux, hardware access
probably is abstracted over a file descriptor and a coroutine interface
would be simple.


Marko



More information about the Python-list mailing list