Python cancel async function

Viewed 175

I'm try to do something like this

def noAsyncPrint(c):
    sleep(random.uniform(1,10))
    print(c)

chars = ['a','b','c']
for c in chars:
    noAsyncPrint(c)

getting this output

a, b, c

How I get some random order?? thank you :)

edit to be clear about my example
**It's just basic example for being clear, It should be random api request after doing few things **

3 Answers

you can use ThreadPool from multiprocessing.pool :

from multiprocessing.pool import ThreadPool
from time import sleep
import random

def noAsyncPrint(c):
    sleep(random.uniform(1,10))
    print(c)

chars = ['a','b','c']
    
with ThreadPool(3) as p:
    p.map(noAsyncPrint, chars)

output:

a
c
b

the output is random, can be any combination

in the above code, you are using 3 threads that will execute your function noAsyncPrint in an asynchronous fashion so your output is random

You might want to use the asyncio library. Checkout this guide for a nice walk-through. The following example uses the gather() function to schedule the async_print() in a concurrent fashion. I also added logging with time stamp to make the execution order visible:

import logging
import random
import asyncio

lgr = logging.getLogger('main')


async def async_print(c):
    tau = round(random.uniform(1,10))
    lgr.debug(f"async_print('%s'): - sleeping of %g sec ...", c, tau)
    await asyncio.sleep(tau)
    lgr.debug(f"async_print('%s'): ... done sleeping.", c)
    print(c)


async def main():
    chars = ['a','b','c']
    lgr.info("Creating futures... ")
    list_of_futures = [async_print(c_) for c_ in chars]
    lgr.debug("Calling futures concurrently ... ")
    await asyncio.gather(*list_of_futures)
    lgr.info(" ... done.")


logging.basicConfig(level=logging.DEBUG, datefmt="%H:%M:%S",
                    format='%(asctime)s %(name)s[%(lineno)s] %(levelname)s %(message)s')
asyncio.run(main())

The output looks like this:

15:17:56 asyncio[59] DEBUG Using selector: EpollSelector
15:17:56 main[17] INFO Calling futures ... 

15:17:56 main[19] DEBUG Waiting for completion ... 
15:17:56 main[9] DEBUG async_print('a'): - sleeping of 9 sec ...
15:17:56 main[9] DEBUG async_print('b'): - sleeping of 9 sec ...
15:17:56 main[9] DEBUG async_print('c'): - sleeping of 1 sec ...
15:17:57 main[11] DEBUG async_print('c'): ... done sleeping.
c
a
b
15:18:05 main[11] DEBUG async_print('a'): ... done sleeping.
15:18:05 main[11] DEBUG async_print('b'): ... done sleeping.
15:18:05 main[21] INFO  ... done.

Note that the print() function does not always display the output immediately. The logging functions behave much better in that regard.

in the numpy library, there is a function for random order, called np.random.suffle()

import numpy as np # import the numpy lybrary

def noAsyncPrint(c):
    sleep(random.uniform(1,10))
    print(c)

chars = np.array(['a','b','c']) #make it a np array
random_chars = np.random.suffle(chars) # shuffle it!

for c in random_chars:
    noAsyncPrint(c)
Related