1

I have some asyncio tasks and I need to pause all of them. This is my part of code:

import asyncio import random async def workers1(): while True: k = random.randint(100, 200) await asyncio.sleep(k) await my_print(k) async def workers2(): while True: k = random.randint(100, 200) await asyncio.sleep(k) await my_print(k) async def my_print(k): print(k) if k == 122: >>>>>>> suspend all of workers while k != 155: k = await repair() await asyncio.sleep(1) r>>>>>> resume all of workers async def main(): tasks = [asyncio.create_task(workers1()), asyncio.create_task(workers2()) ] [await x for x in tasks] if __name__ == '__main__': asyncio.run(main()) 

How can I suspend all of workers in my code when trouble happens in a function my_print and after repair in my_print resume all of tasks?

I will be glad if you give an example. I have been seen this link. But that's not what I need.

4
  • I think you should clearly explain why the question you linked is not what you need. Is it that you need to suspend routines without wrapping the task runners? If so edit your question to say that. Commented Jan 31, 2023 at 1:11
  • @Sam Hartman - I will need to run another task while the others are sleeping Commented Jan 31, 2023 at 22:26
  • What does ">>>>>>>" and "r>>>>>>" mean? The syntax highlighter is not fond of it. Commented Feb 2, 2023 at 3:23
  • @Peter Mortensen - these are just signs to draw attention to this part of the code Commented Feb 2, 2023 at 15:43

2 Answers 2

1

Simply replace your call to await asyncio.sleep(1) with time.sleep(1). If your code doesn't have an await expression in it, all the other tasks are effectively blocked.

import asyncio import random import time async def workers1(): while True: k = random.randint(100, 200) await asyncio.sleep(k) await my_print(k) async def workers2(): while True: k = random.randint(100, 200) await asyncio.sleep(k) await my_print(k) async def my_print(k): print(k) if k == 122: >>>>>>> suspend all of workers while k != 155: k = random.randint(100, 200) time.sleep(1.0) # CHANGE HERE r>>>>>> resume all of workers async def main(): tasks = [asyncio.create_task(workers1()), asyncio.create_task(workers2()) ] [await x for x in tasks] if __name__ == '__main__': asyncio.run(main()) 
Sign up to request clarification or add additional context in comments.

1 Comment

i know that time - is blocking but i need to run repair another task while others are sleeping, thanks bro , but it is won't work in my case
0

So, first, note that the time.sleep trick can be replaced with any non-asynchronous code. So you can do anything that runs synchronously instead of time.sleep. Including set up a second asyncio loop in a different thread and run tasks in that loop. The following code uses ThreadPoolExecutor from concurrent.futures to set up a new event loop. In particular:

 future = executor.submit(asyncio.run, task_3()) 

Will set up a new thread and run task_3 in that new loop. The next line future.result() blocks the entire first loop (task_1 and task_2) until task_3 exits. In task_3 you can do any asyncio operations you like, and until that exits all of the existing tasks will be suspended.

import asyncio, concurrent.futures async def task_1(): while True: print('task 1 runs') await asyncio.sleep(1) async def task_2(): print('task 2 starts') await asyncio.sleep(5) print('first set of tasks suspends') future = executor.submit(asyncio.run, task_3()) print('suspending existing tasks') future.result() print('resuming tasks') async def task_3(): print('task 3 runs') await asyncio.sleep(4) print('task 3 finishes') async def main(): asyncio.ensure_future(task_1()) asyncio.ensure_future(task_2()) await asyncio.sleep(15) executor = concurrent.futures.ThreadPoolExecutor() asyncio.run(main()) 

2 Comments

it works great!!!!!! Thank you very much, and please tell me what to do if there are 4 tasks and only 2 specific ones need to be stopped?
If you only need to suspend some tasks you need something likke Suspendable from the answer you didn't like. Basically you need to be able to interpose something in front of the task that asks it to suspend. You might also be able to subclass Task. It's going to be a significant mess. You are better off refactoring your code and using something like asyncio.Event or asyncio.Semaphore to allow you to block a task at appropriate points. You'd need to share a lot more detail of your problem to get a goodsolution; probably another question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.