A note about blocking functions

As you have seen, we have to replace our original time.sleep() function with its equivalent from the asyncio module. This is because time.sleep() is, by nature, a blocking function, which means that it cannot be used to implement a task switching event. To test this, in our Chapter10/example2.py file (our asynchronous program), we will replace the following line of code:

await asyncio.sleep(delay)

The preceding code will be replaced with the following code:

time.sleep(delay)

After running this new script, your output will simply be the same as that of our original sequential, synchronous program. So, replacing await asyncio.sleep() with time.sleep() actually converts our program back to synchronous, ignoring the event loop that we implemented. What happened was, when our program proceeded to that line inside of the count_down() function, time.sleep() actually blocked and prevented the release of the execution flow, essentially rendering the whole program synchronous once again. Revert time.sleep() back to await asyncio.sleep() to fix this problem.

The following diagram illustrates an example of the difference in execution time between blocking and non-blocking file handling:

Blocking versus non-blocking

This phenomenon raises an interesting issue: if a heavy, long-running task is blocking, then it is literally impossible to implement asynchronous programming with that task as a coroutine. So, if we really wanted to achieve what a blocking function returns in an asynchronous application, we would need to implement another version of that blocking function, which could be made into a coroutine and allow for task switching events to take place at at least one point inside the function.

Luckily, after implementing asyncio as one of the official features of Python, Python core developers have been on working to produce the coroutine version of the most commonly used Python blocking functions. This means that if you ever find blocking functions that prevent your program from being truly asynchronous, you will most likely be able to find the coroutine versions of those functions to implement in your program.

However, the fact that there are asynchronous versions of traditionally blocking functions in Python with potentially different APIs means that you will need to familiarize yourself with those APIs from separate functions. Another way to handle blocking functions without having to implement their coroutine versions is to use an executor to run the functions in separate threads or separate processes, to avoid blocking the thread of the main event loop.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.216.47.169