Mark Estrada
Mark Estrada

Reputation: 9201

Sharing data between AsyncIO

I am trying to understand asyncio and queue so I got this sample from this question to try on How to exchange values betwwen async function which are running forever in python3.5?

import asyncio
import random

class Demo:
    def __init__(self):
        self.ltp = 0
        self.queue = asyncio.Queue(1)

    async def one(self):
        while True:
            print("Here in one()")
            self.ltp += random.uniform(-1, 1)
            print("one() is sleeping.. value generated = " + str(self.ltp))
            await self.queue.put(self.ltp)

    async def two(self):
        while True:
            print("Here in two()")
            print(self.ltp)
            print("two() is sleeping..")
            await asyncio.sleep(0)

    print("---------------Start----------------")
    loop = asyncio.get_event_loop()
    d = Demo()
    loop.create_task(d.one())
    loop.create_task(d.two())
    loop.run_forever()

As I looked at the code output, i noticed that the one() function is never called anymore. Is there a way to have the two() function give back to one() so that it will get a chance to update its values?

---------------Start----------------
Here in one()
one() is sleeping.. value generated = 0.0018691287572603077
Here in one()
one() is sleeping.. value generated = 0.9143832681012423
Here in two()
0.9143832681012423
two() is sleeping..
Here in two()
0.9143832681012423
two() is sleeping..
Here in two()
0.9143832681012423
two() is sleeping..
Here in two()
0.9143832681012423
two() is sleeping..
Here in two()
0.9143832681012423
two() is sleeping..
Here in two()
0.9143832681012423
two() is sleeping..
Here in two()
0.9143832681012423
two() is sleeping..
Here in two()
0.9143832681012423
two() is sleeping..
Here in two()
0.9143832681012423
two() is sleeping..
Here in two()
0.9143832681012423
two() is sleeping..
Here in two()
0.9143832681012423
two() is sleeping..
Here in two()
0.9143832681012423
two() is sleeping..
Here in two()
0.9143832681012423
two() is sleeping..
Here in two()
0.9143832681012423
two() is sleeping..
Here in two()
0.9143832681012423
two() is sleeping..
Here in two()
0.9143832681012423
two() is sleeping..
Here in two()
0.9143832681012423
two() is sleeping..
Here in two()
0.9143832681012423
two() is sleeping..
Here in two()
0.9143832681012423
two() is sleeping..
Here in two()
0.9143832681012423
two() is sleeping..
Here in two()
0.9143832681012423
two() is sleeping..
Here in two()
0.9143832681012423
two() is sleeping..
Here in two()
0.9143832681012423
two() is sleeping..
Here in two()
0.9143832681012423
two() is sleeping..
Here in two()
0.9143832681012423
two() is sleeping..
Here in two()
0.9143832681012423
two() is sleeping..
Here in two()
0.9143832681012423
two() is sleeping..
Here in two()
0.9143832681012423
two() is sleeping..
Here in two()
0.9143832681012423
two() is sleeping..
Here in two()
0.9143832681012423
two() is sleeping..
Here in two()
0.9143832681012423
two() is sleeping..
Here in two()
0.9143832681012423
two() is sleeping..
Here in two()
0.9143832681012423
two() is sleeping..
Here in two()
0.9143832681012423
two() is sleeping..
Here in two()
0.9143832681012423
two() is sleeping..
Here in two()
0.9143832681012423
two() is sleeping..
Here in two()
0.9143832681012423
two() is sleeping..
Here in two()
0.9143832681012423
two() is sleeping..
Here in two()
0.9143832681012423
two() is sleeping..
Here in two()
0.9143832681012423

Upvotes: 0

Views: 1464

Answers (1)

Sam H.
Sam H.

Reputation: 4359

I think the following code will behave closer to how you expected:

import asyncio
import random


class Demo:
    def __init__(self):
        self.ltp = 0
        self.queue = asyncio.Queue(1)

    async def one(self):
        while True:
            print("Here in one()")
            self.ltp += random.uniform(-1, 1)
            print(f"value generated = {str(self.ltp)}")
            await self.queue.put(self.ltp)

    async def two(self):
        while True:
            print("Here in two()")
            val = await self.queue.get()
            print(f"I see {val}")


if __name__ == "__main__":
    d = Demo()
    try:
        print("---------------Start----------------")
        loop = asyncio.get_event_loop()
        asyncio.ensure_future(d.one())
        asyncio.ensure_future(d.two())
        loop.run_forever()
    except Exception:
        pass
    finally:
        print("step: loop.close()")
        loop.close()

This generates the output:

---------------Start----------------
Here in one()
value generated = -0.6413903994469317
Here in one()
value generated = -1.0685807532617448
Here in two()
I see -0.6413903994469317
Here in two()
Here in one()
value generated = -0.8610724954475495
I see -1.0685807532617448
Here in two()
Here in one()
value generated = -0.7267456040329765
I see -0.8610724954475495
Here in two()
Here in one()
value generated = -1.0264441768086192
I see -0.7267456040329765
Here in two()
Here in one()
value generated = -1.8992963343639357
I see -1.0264441768086192
Here in two()
Here in one()
value generated = -1.2370609104359145
I see -1.8992963343639357
Here in two()
Here in one()
value generated = -0.9568062439608271
I see -1.2370609104359145
Here in two()
Here in one()
value generated = -0.03401334759258323
I see -0.9568062439608271
Here in two()
Here in one()
value generated = 0.5586981511810925
I see -0.03401334759258323
Here in two()

I say this is closer to what you imagine, because the ordering is not exactly what one would expect from blocking code. That is by design, and a separate question.

Upvotes: 1

Related Questions