0

I have a Python module that calls four other modules. I would like to start them at the same time and let them execute independently.

Currently, however, the module is executing the other modules synchronously / sequentially.

Here's the code.


    import asyncio
    import time

    from module_01 import main_01
    from module_02 import main_02
    from module_03 import main_03
    from module_04 import main_04

    async def say_after(delay, what):
        print(f"Time now {time.strftime('%X')}")                
        await asyncio.sleep(delay)
        what()
        print(f"Exit time {time.strftime('%X')}")     
       
    async def main():
        print(f"Process started at {time.strftime('%X')}")    
        task1 = asyncio.create_task(say_after(0, main_01))
        task2 = asyncio.create_task(say_after(0, main_02))
        task3 = asyncio.create_task(say_after(0, main_03))
        task4 = asyncio.create_task(say_after(0, main_04))
        await task1
        await task2
        await task3
        await task4

        print(f"Process completed at {time.strftime('%X')}")   
 
    asyncio.run(main())

Below are the results.

|Message|My Comment|
|--------|----------|
|Process started at 18:41:49||
|Time now 18:41:49||
|Time now 18:41:49||
|Time now 18:41:49||
|Time now 18:41:49||
|Module_01 completed.||
|Exit time 18:41:50|As expected.|
|Module_02 completed.||
|Exit time 18:41:52|I want this to be 18:41:51.|
|Module_03 completed.||
|Exit time 18:41:55|I want this to be 18:41:52.|
|Module_04 completed.|
|Exit time 18:41:59|I want this to be 18:41:53.|
|Process completed at 18:41:59|Looks like the other modules are executed sequentially which I do not want.|

As a representative, I give below two of the four other modules.

The first module.


    from time import sleep
    
    def main_01():
        sleep(1)
        print ('Module_01 completed.')
    
    #main_01()

The fourth module.


    from time import sleep
    
    def main_04():  
        sleep (4)     
        print ('Module_04 completed.')
        
    
    #main_04()

Interestingly another similar code example is giving results as expected.

Example Code below.


    import asyncio
    import time
    
    async def say_after(delay, what):
        print(f"Time now {time.strftime('%X')}")                    
        await asyncio.sleep(delay)
        print(what)
        print(f"Exit time {time.strftime('%X')}")                
    
    async def main():
        print(f"Process started at {time.strftime('%X')}")    
        task1 = asyncio.create_task(say_after(1, 'hey'))
        task2 = asyncio.create_task(say_after(2, 'there,'))
        task3 = asyncio.create_task(say_after(3, 'what\'s'))
        task4 = asyncio.create_task(say_after(4, 'up?'))

        # Wait until tasks are completed (should take
        # around 4 seconds.)

        await task1
        await task2
        await task3
        await task4
        print(f"finished at {time.strftime('%X')}")

    asyncio.run(main())   

Here are the results.

|Message|
|----------|
|Process started at 18:56:32|
|Time now 18:56:32|
|Time now 18:56:32|
|Time now 18:56:32|
|Time now 18:56:32|
|hey|
|Exit time 18:56:33|
|there,|
|Exit time 18:56:34|
|what's|
|Exit time 18:56:35|
|up?|
|Exit time 18:56:36|
|finished at 18:56:36|

This example tells me that the say_after function is executed asynchronously and the overall module finishes after 4 seconds.

I know that both modules are different and the one which I want to give the expected results (4 seconds overall execution time) calls other Python modules. Is this the issue here? If not, where is the issue, please?

Thank you.

Regards

Manoj.

petezurich
  • 9,280
  • 9
  • 43
  • 57
MDixit
  • 3
  • 2
  • 1
    You use `time.sleep()` in your modules, which is synchronous/blocking, so you end up serializing your module execution. You want [`asyncio.sleep()`](https://docs.python.org/3/library/asyncio-task.html#asyncio.sleep) which allows the coroutines to suspend. – wkl Aug 14 '22 at 18:24
  • @wki is absolutely correct. This is a very common mistake. I almost wished that Python would give a warning or error when calling `time.sleep()` inside asynchronous code. – Frank Yellin Aug 14 '22 at 18:31
  • Possible Duplicate/Does this answer your question? [asyncio.sleep() vs time.sleep()](https://stackoverflow.com/questions/56729764/asyncio-sleep-vs-time-sleep) – wkl Aug 14 '22 at 18:34
  • Thanks @wkl and Frank. I am exploring how it's done in Python. Completely missed the differences. Wkl, the link is useful. Thank you. – MDixit Aug 14 '22 at 18:37

1 Answers1

0

Posting to mark the question as answered.


    await asyncio.sleep(1)

helped to solve the issue.

MDixit
  • 3
  • 2
  • I want to mark wkl's answer as correct but not sure how it's done. Just want to give credit where it's due. – MDixit Aug 14 '22 at 18:43