파이썬, 동기식, 비동기식(구형/신형) 함수 사용 비교 예제 2

 

글. 수알치 오상문

 

이전 글에 다뤘던 예제를 변경한 것입니다. 비동기 호출한 함수의 처리 결과 값을 전역변수 또는 return으로 다루는 방법을 보여줍니다. 

 

import time
import asyncio

result1 = []
result2 = []
result3 = []
result4 = []


# 비동기식 함수 (작업 대상)
async def find_users_async(n, result):
    for i in range(1, n + 1):
        print(f'{n} times')
        await asyncio.sleep(1)  # 비동기식 지연 함수
    result.append({n: "SUCCESS"})    
    print(f'{n} 작업 완료')


# 비동기식 함수2 (작업 대상) : return value
async def find_users_async2(n):
    start = time.time()      
    for i in range(1, n + 1):
        print(f'{n} times')
        await asyncio.sleep(1)  # 비동기식 지연 함수
    end = time.time()    
    return(end - start)    
    print(f'{n} 작업 완료')    


# 동기식 함수 (작업 대상)
def find_users(n, result):  
    for i in range(1, n + 1):
        print(f'{n} times')
        time.sleep(1)
    result.append({n: "SUCCESS"})        
    print(f'{n} 작업 완료')


#---------------------------------------
    
# 동기식 호출 함수 : 동기식 작업 대상을 호출하는 함수 
def func_sync():
    start = time.time()
    find_users(3, result1)
    find_users(2, result1)
    find_users(1, result1)    
    end = time.time()
    print(f'>>> 동기 처리 총 소요 시간: {end - start}')


# 비동기식 호출 함수 : 비동기 작업 대상을 호출하는 함수 (예전 방식)
async def func_async():
    start = time.time()
    await asyncio.wait([
        find_users_async(3, result2),
        find_users_async(2, result2),
        find_users_async(1, result2),
    ])
    end = time.time()
    print(f'>>> 비동기 처리 총 소요 시간: {end - start}')


# 비동기식 호출 함수 : 비동기 작업 대상을 호출하는 함수 (새 방식)
# 호출 결과는 result3 리스트에 저장된다.
async def func_async_new():
    global result3
    start = time.time()
    await asyncio.wait([
        asyncio.create_task(find_users_async(3, result3)),
        asyncio.create_task(find_users_async(2, result3)),
        asyncio.create_task(find_users_async(1, result3)),
    ])
    end = time.time()
    print(f'>>> 비동기 처리 총 소요 시간: {end - start}')


# 비동기식 호출 함수 new 2: 비동기 함수 호출 후 리턴 값 처리하기
iteration_times = [1, 3, 2]

async def func_async_new2():
    global result4
    tasks = []

    # 이 방식은 에러 발생!!!    
##    await asyncio.wait([
##        tasks.append(asyncio.create_task(find_users_async2(3))),
##        tasks.append(asyncio.create_task(find_users_async2(2))),
##        tasks.append(asyncio.create_task(find_users_async2(1))),
##    ])

    # 개별적으로 asyncio.create_task() 등록 : OK    
    for i, second in enumerate(iteration_times):
        tasks.append(asyncio.create_task(find_users_async2(second)))
        
    return await asyncio.gather(*tasks)


# 테스트 -------------------------------------
if __name__ == '__main__':
    
    func_sync()  # 동기 방식 테스트 
    # asyncio.run(func_async())  # 비동기 방식 테스트(구형)
    asyncio.run(func_async_new())  # 비동기 방식 테스트(신형): 전역변수에 저장
    ret = asyncio.run(func_async_new2()) # 비동기 방식 테스트(신형): return 방식 
    
    print('result1:', *result1)
    print('result2:', *result2)
    print('result3:', *result3)    
    print('return:' , *ret)


반응형

+ Recent posts