Event Loop

Python SELF KO
레벨 25 , 레슨 5
사용 가능

6.1 이벤트 루프 얻기

이벤트 루프 (Event Loop) 는 Python의 asyncio 모듈을 사용한 비동기 프로그래밍의 중심 요소야. 이건 비동기 태스크 처리, 이벤트 처리를 관리하고 입출력 연산을 수행해. 이벤트 루프는 여러 태스크가 동시에 실행되도록 해서 메인 스레드가 막히지 않도록 도와줘.

이벤트 루프 생성 및 얻기

  • asyncio.get_event_loop(): 현재 이벤트 루프를 반환하거나, 없으면 새로 만들어 줘.
  • asyncio.new_event_loop(): 새로운 이벤트 루프를 만들어.
  • asyncio.set_event_loop(loop): 지정된 이벤트 루프를 현재 루프로 설정해.

예시:

asyncio에는 실행 중인 모든 태스크를 포함하는 현재의 이벤트 루프가 있어. 이 루프를 얻거나 새로 만들어서 현재 루프로 설정할 수 있어. 아래 예시에서 볼 수 있는 것처럼 말이야.


import asyncio

loop = asyncio.get_event_loop()
print(loop)  # 현재 이벤트 루프
new_loop = asyncio.new_event_loop()
asyncio.set_event_loop(new_loop)
print(asyncio.get_event_loop())  # 새로 설정된 이벤트 루프

get_event_loop() 메소드는 현재 활성화된 이벤트 루프를 반환해. 새로운 이벤트 루프를 만들고 설정하는 것은 비동기 애플리케이션에서 충돌을 피하기 위해 신중하게 사용해야 해.

이벤트 루프 실행하기

  • run_forever(): 이벤트 루프를 실행하고 stop()이 호출될 때까지 계속 진행해.
  • run_until_complete(future): 주어진 코루틴이나 future 객체가 완료될 때까지 이벤트 루프를 실행해.

예시:

이벤트 루프는 두 가지 모드로 실행할 수 있어: 무한히 실행되는 것 — while True 같은 거, 아니면 특정 태스크가 완료될 때까지.


import asyncio

async def hello():
    print("Hello")
    await asyncio.sleep(1)
    print("World")
            
loop = asyncio.get_event_loop()
loop.run_until_complete(hello())
loop.close()

만약 Event Looprun_forever() 모드에서 실행하면, 이것은 내부에서 무한히 루프를 돌게 될 거야. run_forever() 메소드는 어떤 비동기 태스크가 EventLoopstop() 메소드를 호출하지 않는 한 종료되지 않아.

이벤트 루프 중지하기

  • stop(): 이벤트 루프를 중지해.
  • is_running(): 이벤트 루프가 실행 중이라면 True를 반환해.

예시:

무한 모드에서 루프가 실행 중이면 태스크를 계속 받고 처리해, 그래서 자체적으로는 멈추지 않아. 누군가가 현재 루프의 객체를 얻고 stop() 메소드를 호출해야 해. 무한 루프가 실행 중인지 아닌지를 알기 위해선 is_running() 메소드를 호출해야 해.


import asyncio
            
loop = asyncio.get_event_loop()
loop.stop()
print(loop.is_running())  # False

6.2 이벤트 루프의 중요한 메소드

call_soon(callback, *args) 메소드

가능한 빨리 callback 함수와 *args 인수를 호출하도록 계획해.


import asyncio

def my_callback():
    print("Callback executed")
            
loop = asyncio.get_event_loop()
loop.call_soon(my_callback)
loop.run_forever()

callback 함수를 태스크 리스트 맨 앞에 넣어서 가능한 한 빨리 실행되도록 해. 이 메소드는 비동기 함수가 아닌 함수도 전달할 수 있어. 비동기 애플리케이션에서 즉시 응답이 필요할 때 이 메소드는 유용해.

call_later(delay, callback, *args) 메소드

delay 초 후에 callback 함수와 *args 인수를 호출하도록 계획해.


import asyncio

def my_callback():
    print("Callback executed after delay")
            
loop = asyncio.get_event_loop()
loop.call_later(2, my_callback)
loop.run_forever()

이 메소드는 함수 호출을 지연해서 수행할 수 있게 해줘: 첫 번째 매개변수로 초 단위의 지연 시간을 받지 (소수점 가능), 그다음엔 함수와 그 인자를 받아. 비동기 함수가 아닌 함수도 전달할 수 있어. 이 메소드는 다양한 우선순위로 태스크를 관리할 때 유용해, 특히 복잡한 비동기 시스템을 설계할 때 말이야.

call_at(when, callback, *args) 메소드

when 시간에 callback 함수와 *args 인수를 호출하도록 계획해.


import asyncio
import time
            
def my_callback():
    print("Callback executed at specific time")
            
loop = asyncio.get_event_loop()
when = loop.time() + 2  # 이벤트 루프의 현재 시간으로부터 2초 후
loop.call_at(when, my_callback)
loop.run_forever()

5초 후가 아니라, 예를 들어 15:00이나 24:00에 태스크를 실행하고 싶다면, call_at() 함수를 사용하는 것이 좋아. 이건 call_soon() 함수처럼 동작하지만, 첫 번째 매개변수로 지연 시간 대신 특정 호출할 시간을 받아. 비동기 함수가 아닌 함수도 전달할 수 있어.

장점 및 특징

비동기 실행: 이벤트 루프가 메인 스레드를 막지 않고 동시에 많은 태스크를 실행할 수 있도록 해줘.

효율적인 리소스 관리: 비동기 입출력 작업이 블록 없이 수행되어 프로그램을 더 효율적으로 만들어줘.

유연성과 확장성: 이벤트 루프는 많은 태스크 스케줄링과 이벤트 처리를 지원해서 복잡하고 확장 가능한 비동기 애플리케이션을 만들 수 있게 해줘.

6.3 태스크 및 Future 객체와의 상호 작용

이벤트 루프는 태스크 (Tasks)와 미래의 객체 (Futures)의 실행을 관리해. 루프는 그들의 상태를 추적하고 준비가 되면 실행을 보장해 줘.

예시:


import asyncio

async def main():
    await asyncio.sleep(1)
    print("Task completed")
            
loop = asyncio.get_event_loop()
task = loop.create_task(main())
loop.run_until_complete(task)

이 예시에서는 create_task 메소드를 사용해서 생성된 태스크의 실행을 이벤트 루프가 어떻게 관리하는지를 보여줘. call_soon(), call_later(), 그리고 call_at() 메소드들은 다양한 우선순위로 태스크 실행을 관리하는 데 유용해, 특히 복잡한 비동기 시스템을 설계할 때 말이야.

1
설문조사/퀴즈
멀티스레드, 레벨 25, 레슨 5
사용 불가능
멀티스레드
멀티스레드
코멘트
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION