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 Loop
๋ฅผ run_forever()
๋ชจ๋์์ ์คํํ๋ฉด, ์ด๊ฒ์ ๋ด๋ถ์์ ๋ฌดํํ ๋ฃจํ๋ฅผ ๋๊ฒ ๋ ๊ฑฐ์ผ. run_forever()
๋ฉ์๋๋ ์ด๋ค ๋น๋๊ธฐ ํ์คํฌ๊ฐ EventLoop
์ stop()
๋ฉ์๋๋ฅผ ํธ์ถํ์ง ์๋ ํ ์ข
๋ฃ๋์ง ์์.
์ด๋ฒคํธ ๋ฃจํ ์ค์งํ๊ธฐ
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()
๋ฉ์๋๋ค์ ๋ค์ํ ์ฐ์ ์์๋ก ํ์คํฌ ์คํ์ ๊ด๋ฆฌํ๋ ๋ฐ ์ ์ฉํด, ํนํ ๋ณต์กํ ๋น๋๊ธฐ ์์คํ
์ ์ค๊ณํ ๋ ๋ง์ด์ผ.
GO TO FULL VERSION