Software Development/Python

[Python] 파이썬 - asyncio callback 알아보기

루ㅌ 2020. 9. 24. 20:19

아래의 정의는 위키피디아에서 가져온 callback(콜백)에 대한 정의이다.

 

콜백(callback)은 다른 코드의 인수로서 넘겨주는 실행 가능한 코드를 말한다. 콜백을 넘겨받는 코드는 이 콜백을 필요에 따라 즉시 실행할 수도 있고, 아니면 나중에 실행할 수도 있다.

 

아래는 파이썬 공식 문서의 예제를 변형 시킨 코드이다.

 

import asyncio
import datetime
import time
import random 
def display_date(end_time, loop, count):
    now_time = datetime.datetime.now()
    print(now_time)
    if (loop.time() + 1.0) < end_time:
        ran_int = random.randint(0, 3)
        time.sleep(ran_int)
        print('call soon', now_time, "random sleep int : ", ran_int, 'count: ', count)

        loop.call_soon(display_date, end_time, loop, count + ' 0')
        loop.call_soon(display_date, end_time, loop, count + ' 1')
        loop.call_soon(display_date, end_time, loop, count + ' 2')
    else:
        loop.stop()

loop = asyncio.get_event_loop()

# Schedule the first call to display_date()
end_time = loop.time() + 20.0
loop.call_soon(display_date, end_time, loop, '0')

# Blocking call interrupted by loop.stop()
try:
    loop.run_forever()
finally:
    loop.close()

 

실행결과를 보면 아래와 같다.

2020-09-24 11:11:53.768732
call soon 2020-09-24 11:11:53.768732 random sleep int :  3 count:  0
2020-09-24 11:11:56.795639
call soon 2020-09-24 11:11:56.795639 random sleep int :  2 count:  0 0
2020-09-24 11:11:58.800279
call soon 2020-09-24 11:11:58.800279 random sleep int :  2 count:  0 1
2020-09-24 11:12:00.813895
call soon 2020-09-24 11:12:00.813895 random sleep int :  0 count:  0 2
2020-09-24 11:12:00.815892
call soon 2020-09-24 11:12:00.815892 random sleep int :  0 count:  0 0 0
2020-09-24 11:12:00.817885
call soon 2020-09-24 11:12:00.817885 random sleep int :  2 count:  0 0 1
2020-09-24 11:12:02.828509
call soon 2020-09-24 11:12:02.828509 random sleep int :  0 count:  0 0 2

 

 

call_soon을 통해 비동기적으로 실행되는 것을 볼 수 있다.

 

만일 비동기적으로 실행되지 않으면 어떻게 될까? 아래는 순차적으로 실행되는 코드이다.

 

import asyncio
import datetime
import time
import random 
def display_date(end_time, loop, count):
    now_time = datetime.datetime.now()
    print(now_time)
    if (loop.time() + 1.0) < end_time:
        ran_int = random.randint(0, 3)
        time.sleep(ran_int)
        display_date(end_time, loop, count + ' 0')
        display_date(end_time, loop, count + ' 1')
        display_date(end_time, loop, count + ' 2')
        print('call soon', now_time, "random sleep int : ", ran_int, 'count: ', count)
    else:
        loop.stop()

loop = asyncio.get_event_loop()

# Schedule the first call to display_date()
end_time = loop.time() + 20.0
loop.call_soon(display_date, end_time, loop, '0')

# Blocking call interrupted by loop.stop()
try:
    loop.run_forever()
finally:
    loop.close()

 

 

위 코드의 출력은 다음과 같다. 

2020-09-24 11:10:52.503539
2020-09-24 11:10:53.510844
2020-09-24 11:10:54.511169
2020-09-24 11:10:54.511169
2020-09-24 11:10:56.524787
2020-09-24 11:10:59.531746
2020-09-24 11:11:01.543368
2020-09-24 11:11:03.554989
2020-09-24 11:11:03.555989
2020-09-24 11:11:06.567933
2020-09-24 11:11:07.568259
2020-09-24 11:11:08.582546

보면 call_soon ...과 같은 형식의 print가 출력되지 않은 채 실행된다. 

 

끊임없이 재귀적으로 print(now_time)만 실행하고 첫번째 display_date를 계속해서 재귀적으로 실행하는 것이다.

 

callback은 이 처럼 비동기적으로 코드를 실행할 수 있도록 해준다.