i have bunch of coroutines doing work
@asyncio.coroutine def do_work(): global counter result = ... if result.status == 'ok': counter += 1 and 1
counter = 0 @asyncio.coroutine def display_status(): while true: print(counter) yield asyncio.sleep(1) which have display how many coroutines have finished work. how implement task? following solution doesn't work
@asyncio.coroutine def spawn_jobs(): coros = [] in range(10): coros.append(asyncio.task(do_work())) yield asyncio.gather(*coros) if __name__ == '__main__': loop = asyncio.get_event_loop() loop.create_task(display_status()) loop.run_until_complete(spawn_jobs()) loop.close() i expect counter printed console every second no matter do_work() coroutines do. have 2 outputs: 0 , after few seconds repeating 10.
but have 2 outputs: 0 , after few seconds repeating 10.
i can't reproduce it. if use:
import asyncio import random @asyncio.coroutine def do_work(): global counter yield asyncio.sleep(random.randint(1, 5)) counter += 1 i output this:
0 0 4 6 8 task destroyed pending! task: <task pending coro=<display_status() running @ most_wanted.py:16> wait_for=<future pending cb=[task._wakeup()] created @ ../lib/asyncio/tasks.py:490> created @ most_wanted.py:27> the infinite loop in display_status() causes warning @ end. avoid warning; exit loop when tasks in batch done:
#!/usr/bin/env python3 import asyncio import random contextlib import closing itertools import cycle class batch: def __init__(self, n): self.total = n self.done = 0 async def run(self): await asyncio.wait([batch.do_work() _ in range(batch.total)]) def running(self): return self.done < self.total async def do_work(self): await asyncio.sleep(random.randint(1, 5)) # work here self.done += 1 async def display_status(self): while self.running(): await asyncio.sleep(1) print('\rdone:', self.done) async def display_spinner(self, char=cycle('/|\-')): while self.running(): print('\r' + next(char), flush=true, end='') await asyncio.sleep(.3) closing(asyncio.get_event_loop()) loop: batch = batch(10) loop.run_until_complete(asyncio.wait([ batch.run(), batch.display_status(), batch.display_spinner()])) output
done: 0 done: 2 done: 3 done: 4 done: 10
Comments
Post a Comment