1

How to await while loop? I have the following code snippet:

import asyncio
from asyncio.tasks import sleep
import time

running = True

async def f1():
    global running
    print(f"Running: {running}")
    print("f1() started.")

    ### await the while loop below
    while running:
        print(f"Inside while loop")
    ###

    print(f"Running: {running}")
    print("f1() ended")

async def f2():
    global running
    print("f2() started.")
    
    # this should be blocking code
    time.sleep(0.5)
    
    print("f2 ended.")
    running = False

async def main():
    await asyncio.gather(f1(), f2())

asyncio.run(main())

Basically, what I want is:

# 1. Start f1(). f1() has a while loop.
# 2. Start f2().
# 3. Notify f1() to break the while loop.
0

2 Answers 2

2

I guess you have to put in some await asyncio.sleep(0) or so into the while loop, not sure if it works with 0 but just put a small number. It just has to be some await call that gives others the chance to do

import asyncio
from asyncio.tasks import sleep
import time

running = True


async def f1():
    global running
    print(f"Running: {running}")
    print("f1() started.")

    ### await the while loop below
    while running:
        print(f"Inside while loop")
        await asyncio.sleep(0)
    ###

    print(f"Running: {running}")
    print("f1() ended")


async def f2():
    global running
    print("f2() started.")

    # this should be blocking code
    time.sleep(0.5)

    print("f2 ended.")
    running = False


async def main():
    await asyncio.gather(f1(), f2())


asyncio.run(main())

that works for me

Sign up to request clarification or add additional context in comments.

Comments

1

Without globals:

import asyncio
from asyncio.tasks import sleep
import time


async def f1( q ):
    print("f1() started.")

    ### await the while loop below
    ## Start listener
    event = asyncio.ensure_future( q.get() )
    while True:
        print( "Inside While Loop" )
        if event.done():
            break
        else: 
            await asyncio.sleep( 0.01 )

    ###

    print("f1() ended")

async def f2( q ):
    print("f2() started.")
    
    # this should be blocking code
    time.sleep( 3 )
    
    print("f2 ended.")
    await q.put( 1 )

async def main():
    q = asyncio.Queue( 1 )
    await asyncio.gather(f1( q ), f2( q ))

asyncio.run(main())

But, since f2 is blocking it wont actually print "Inside event loop" while it is being blocked

So you'll get output like

f1() started.
Inside While Loop
f2() started.
f2 ended.
Inside While Loop
f1() ended

Also you can put just about anything in that queue, doesnt have to be 1.

1 Comment

Also, if you don't want the blocking function to be blocked you can put it in an executor and await it that works wonderfully

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.