How can i wait for task until complete when the task is created by create_task()?

168 views
Skip to first unread message

Bright Pan

unread,
Mar 21, 2016, 3:22:45 AM3/21/16
to python-tulip
HI,
i write a test program for create_task, see the following:

the function a() must be not coroutine,
How can i wait for the task until complete?

thanks!

import asyncio

class Test(object):

def __init__(self):
print(self.__class__.__name__)
pass
@asyncio.coroutine
def greet_every_one_seconds(self, db):
print('Hello World, one second.')
fut =
asyncio.sleep(1,result=4)
a =
yield from fut
print(a)

def a(self):

loop = asyncio.get_event_loop()

task = loop.create_task(self.greet_every_one_seconds(self.db_presell))
#How can i wait for the task until complete?

@asyncio.coroutine
def greet_every_two_seconds(self):
while True:
self.a()
print('Hello World, two seconds.')
yield from asyncio.sleep(2)


if __name__ == '__main__':
test = Test()
loop = asyncio.get_event_loop()
try:
loop.run_until_complete(test.greet_every_two_seconds())
finally:
loop.close()

Victor Stinner

unread,
Mar 21, 2016, 5:15:46 AM3/21/16
to Bright Pan, python-tulip
2016-03-21 8:22 GMT+01:00 Bright Pan <losts...@gmail.com>:
> the function a() must be not coroutine,
> How can i wait for the task until complete?

It's doesn't work well to mix blocking and non-blocking code. I
suggest to convert a() to non-blocking code using @corouting and yield
from/await. If you really want to mix blocking and non-blocking code,
you have two major design choices:

(1) the event loop is the "leader", it schedules blocking tasks using
loop.run_in_executor(): blocking tasks is quite "short" and produces a
result
(2) the blocking code is the "leader", it gives work to the event
loop, and then retrieves results from the event loop

The design (1) fits well into the asyncio design.

The design (2) helps to migrate an existing applications completly
based on blocking code ("regular" Python code), but wants to run some
tasks faster (ex: run multiple network queries in parallel).

For (2), a simple option is to use loop.run_until_complete(). You
schedule many tasks, and then use a simple task to collect all
requests "at once". loop.run_until_complete() blocks the current
thread. In short, you don't run blocking and non-blocking code in
parallel, both modes are exclusive and use the same thread.

A more complex design for (2) is to use two threads: run the event
loop in one thread, and blocking code in a different thread. The
classical option to exchange data (tasks) between the two threads is
to use a queue. For example, the blocking code schedules asynchronous
tasks in the event loop, and then polls the queue to retrieve result.

Victor
Reply all
Reply to author
Forward
0 new messages