๐ Python ๋น๋๊ธฐ ํ๋ก๊ทธ๋๋ฐ: ๋์์ฑ์ผ๋ก ์ฑ๋ฅ ๊ฐ์ ํ๊ธฐ ๐

์๋ , ํ์ด์ฌ ๋ง์คํฐ๊ฐ ๋๊ณ ์ถ์ ์น๊ตฌ๋ค! ์ค๋์ ์ ๋ง ํฅ๋ฏธ์ง์งํ ์ฃผ์ ๋ก ์ฐพ์์์ด. ๋ฐ๋ก Python์ ๋น๋๊ธฐ ํ๋ก๊ทธ๋๋ฐ์ ๋ํด ๊น์ด ํํค์ณ๋ณผ ๊ฑฐ์ผ. ๐
ํน์ ๋ํฌ ์ค์ ์ฌ๋ฌ ๊ฐ์ง ์ผ์ ๋์์ ํ๋ ๊ฑธ ์ข์ํ๋ ์ฌ๋ ์์ด? ์๋ฅผ ๋ค์ด, ์์ ๋ค์ผ๋ฉด์ ์์ ํ๊ณ , ๋์์ ์น๊ตฌ๋ ์นดํกํ๋ ๊ทธ๋ฐ ๊ฑฐ ๋ง์ด์ผ. ๊ทธ๋ ๋ค๋ฉด ๋ํฌ๋ ์ด๋ฏธ '๋น๋๊ธฐ'์ ๊ฐ๋ ์ ์ผ์์์ ์ค์ฒํ๊ณ ์๋ ๊ฑฐ์ผ! ๐
ํ๋ก๊ทธ๋๋ฐ์์๋ ์ด๋ฐ ๊ฐ๋ ์ด ์ ์ฉ๋ผ. ํนํ Python์์๋ ์ด๊ฑธ '๋น๋๊ธฐ ํ๋ก๊ทธ๋๋ฐ'์ด๋ผ๊ณ ๋ถ๋ฌ. ์ค๋์ ์ด ๋ฉ์ง ๊ธฐ์ ์ ๋ํด ์น๊ตฌ์ฒ๋ผ ์ฌ๋ฏธ์๊ฒ ์ค๋ช ํด์ค๊ฒ. ์ค๋น๋๋? ๊ทธ๋ผ ์์ํด๋ณด์๊ณ ! ๐
๐ก ์์ญ๋ฌ์ญ Tip: ๋น๋๊ธฐ ํ๋ก๊ทธ๋๋ฐ์ ์ฒ์์๋ ์ข ์ด๋ ค์ ๋ณด์ผ ์ ์์ด. ํ์ง๋ง ๊ฑฑ์ ๋ง! ์ฐ๋ฆฌ๊ฐ ํจ๊ป ์ฐจ๊ทผ์ฐจ๊ทผ ์์๊ฐ๋ค ๋ณด๋ฉด, ์ด๋์ ๋ ๋น๋๊ธฐ์ ๋ฌ์ธ์ด ๋์ด ์์ ๊ฑฐ์ผ. ๊ทธ๋ฆฌ๊ณ ์ด๋ฐ ์ค๋ ฅ์ ๋์ค์ ์ฌ๋ฅ๋ท ๊ฐ์ ํ๋ซํผ์์ ๋ค ์ฌ๋ฅ์ ๋ฝ๋ด๋ ๋ฐ ํฐ ๋์์ด ๋ ๊ฑฐ์ผ! ๐
๐ ๋น๋๊ธฐ ํ๋ก๊ทธ๋๋ฐ์ด ๋ญ๊ธธ๋?
์, ๋น๋๊ธฐ ํ๋ก๊ทธ๋๋ฐ์ด ๋ญ์ง ํ๋ฒ ์์๋ณผ๊น? ์ฝ๊ฒ ์ค๋ช ํ์๋ฉด, ๋น๋๊ธฐ ํ๋ก๊ทธ๋๋ฐ์ ์ฌ๋ฌ ์์ ์ ๋์์ ์ฒ๋ฆฌํ ์ ์๊ฒ ํด์ฃผ๋ ๋ง๋ฒ ๊ฐ์ ๊ธฐ์ ์ด์ผ. ๐ฒ
์๋ฅผ ๋ค์ด๋ณผ๊ฒ. ๋ ์ง๊ธ ํผ์ ๊ฐ๊ฒ์์ ์ผํ๊ณ ์๋ค๊ณ ์๊ฐํด๋ด. ์๋์ด ํผ์๋ฅผ ์ฃผ๋ฌธํ๋ฉด, ๋ ์ค๋ธ์ ํผ์๋ฅผ ๋ฃ๊ณ 15๋ถ์ ๊ธฐ๋ค๋ ค์ผ ํด. ๊ทธ๋ฐ๋ฐ ๊ทธ 15๋ถ ๋์ ๊ฐ๋งํ ์์ ๊ฑฐ์ผ? ์๋์ง! ๋ค๋ฅธ ์ผ์ ํ ์ ์์์. ์๋ฅผ ๋ค์ด ๋ค๋ฅธ ์๋์ ์ฃผ๋ฌธ์ ๋ฐ๊ฑฐ๋, ํ ์ด๋ธ์ ์ ๋ฆฌํ๊ฑฐ๋, ์๋ฃ์๋ฅผ ์ค๋นํ ์ ์์ด.
์ด๊ฒ ๋ฐ๋ก ๋น๋๊ธฐ ํ๋ก๊ทธ๋๋ฐ์ ํต์ฌ์ด์ผ. ํ ์์ ์ด ๋๋๊ธฐ๋ฅผ ๊ธฐ๋ค๋ฆฌ๋ ๋์ ๋ค๋ฅธ ์์ ์ ์ํํ ์ ์๋ค๋ ๊ฑฐ์ง. coolํ์ง ์์? ๐
์์ ๊ทธ๋ฆผ์ ๋ณด๋ฉด, ๋น๋๊ธฐ ํ๋ก๊ทธ๋๋ฐ์ด ์ด๋ป๊ฒ ์๋ํ๋์ง ํ๋์ ๋ณผ ์ ์์ด. ์ค์์ ํฐ ์์ด ๋น๋๊ธฐ ํ๋ก๊ทธ๋๋ฐ์ ๋ํ๋ด๊ณ , ์ฃผ๋ณ์ ์์ ์๋ค์ ๊ฐ๊ฐ์ ํ์คํฌ๋ฅผ ์๋ฏธํด. ์ด ํ์คํฌ๋ค์ด ๋์์ ์คํ๋๋ฉด์ ํจ์จ์ ์ผ๋ก ์์์ ํ์ฉํ๋ ๊ฑฐ์ง. ๋ฉ์ง์ง ์์? ๐
๊ทธ๋ผ ์ด์ ๋น๋๊ธฐ ํ๋ก๊ทธ๋๋ฐ์ด ์ ์ค์ํ์ง ์์๋ณผ๊น?
- โ ์ฑ๋ฅ ํฅ์: ์ฌ๋ฌ ์์ ์ ๋์์ ์ฒ๋ฆฌํ๋๊น ์ ์ฒด์ ์ธ ์คํ ์๊ฐ์ด ์ค์ด๋ค์ด.
- โ ๋ฆฌ์์ค ํจ์จ์ฑ: CPU์ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ๋ ํจ์จ์ ์ผ๋ก ์ฌ์ฉํ ์ ์์ด.
- โ ๋ฐ์์ฑ ๊ฐ์ : ์ฌ์ฉ์ ์ธํฐํ์ด์ค๊ฐ ๋ ๋ถ๋๋ฝ๊ณ ๋ฐ์์ด ๋นจ๋ผ์ ธ.
- โ ํ์ฅ์ฑ: ๋ ๋ง์ ์์ฒญ์ ๋์์ ์ฒ๋ฆฌํ ์ ์์ด ๋๊ท๋ชจ ์ ํ๋ฆฌ์ผ์ด์ ์ ์ ํฉํด.
์ด๋ ๊ฒ ๋ณด๋๊น ๋น๋๊ธฐ ํ๋ก๊ทธ๋๋ฐ์ด ์ผ๋ง๋ ๊ฐ๋ ฅํ์ง ์๊ฒ ์ง? ๐
๐จ ์ฃผ์์ฌํญ: ๋น๋๊ธฐ ํ๋ก๊ทธ๋๋ฐ์ด ํญ์ ์ข์ ๊ฒ๋ง์ ์๋์ผ. ๋๋ก๋ ์ฝ๋๊ฐ ๋ณต์กํด์ง ์ ์๊ณ , ๋๋ฒ๊น ๋ ์ด๋ ค์์ง ์ ์์ด. ๊ทธ๋์ ์ํฉ์ ๋ง๊ฒ ์ ์ ํ ์ฌ์ฉํ๋ ๊ฒ ์ค์ํด!
์, ์ด์ ๋น๋๊ธฐ ํ๋ก๊ทธ๋๋ฐ์ ๊ธฐ๋ณธ ๊ฐ๋ ์ ์์์ผ๋, ๋ค์์ผ๋ก Python์์ ์ด๋ป๊ฒ ์ด๊ฑธ ๊ตฌํํ๋์ง ์์๋ณผ๊น? ์ค๋น๋๋? ๊ทธ๋ผ ๊ณ ๊ณ ! ๐
๐ Python์์์ ๋น๋๊ธฐ ํ๋ก๊ทธ๋๋ฐ
์, ์ด์ Python์์ ๋น๋๊ธฐ ํ๋ก๊ทธ๋๋ฐ์ ์ด๋ป๊ฒ ๊ตฌํํ๋์ง ์์๋ณผ ์ฐจ๋ก์ผ. Python์ ๋น๋๊ธฐ ํ๋ก๊ทธ๋๋ฐ์ ์ํด asyncio๋ผ๋ ๋ฉ์ง ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ ๊ณตํด. ์ด ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ Python 3.4๋ถํฐ ๋์ ๋๊ณ , ๊ณ์ํด์ ๋ฐ์ ํ๊ณ ์์ด. ๐
asyncio๋ฅผ ์ฌ์ฉํ๋ฉด ์ฝ๋ฃจํด(coroutine)์ด๋ผ๋ ํน๋ณํ ํจ์๋ฅผ ๋ง๋ค ์ ์์ด. ์ฝ๋ฃจํด์ ์คํ ์ค์ ์ผ์ ์ค์ง๋๊ณ ๋์ค์ ๋ค์ ์์๋ ์ ์๋ ํจ์์ผ. ์ด๊ฒ ๋ฐ๋ก ๋น๋๊ธฐ ํ๋ก๊ทธ๋๋ฐ์ ํต์ฌ์ด์ง!
์, ๊ทธ๋ผ ๊ฐ๋จํ ์์ ๋ฅผ ํตํด asyncio๋ฅผ ์ฌ์ฉํด๋ณด์.
import asyncio
async def say_hello(name):
print(f"Hello, {name}!")
await asyncio.sleep(1)
print(f"Goodbye, {name}!")
async def main():
await asyncio.gather(
say_hello("Alice"),
say_hello("Bob"),
say_hello("Charlie")
)
asyncio.run(main())
์ด ์ฝ๋๊ฐ ์ด๋ป๊ฒ ๋์ํ๋์ง ์ค๋ช ํด์ค๊ฒ:
async def
๋ก ์ฝ๋ฃจํด ํจ์๋ฅผ ์ ์ํด.await
ํค์๋๋ ๋น๋๊ธฐ ์์ ์ด ์๋ฃ๋ ๋๊น์ง ๊ธฐ๋ค๋ฆฌ๋ผ๋ ์๋ฏธ์ผ.asyncio.gather()
๋ ์ฌ๋ฌ ์ฝ๋ฃจํด์ ๋์์ ์คํํด.asyncio.run()
์ ๋น๋๊ธฐ ํ๋ก๊ทธ๋จ์ ์ง์ ์ ์ด์ผ.
์ด ์ฝ๋๋ฅผ ์คํํ๋ฉด, "Hello" ๋ฉ์์ง๊ฐ ๊ฑฐ์ ๋์์ ์ถ๋ ฅ๋๊ณ , 1์ด ํ์ "Goodbye" ๋ฉ์์ง๊ฐ ์ถ๋ ฅ๋ผ. ๋ฉ์ง์ง ์์? ๐
์ ๊ทธ๋ฆผ์ asyncio์ ์ด๋ฒคํธ ๋ฃจํ๊ฐ ์ด๋ป๊ฒ ๋์ํ๋์ง๋ฅผ ๋ณด์ฌ์ค. Alice, Bob, Charlie๋ผ๋ ์ธ ๊ฐ์ ํ์คํฌ๊ฐ ๋์์ ์คํ๋๊ณ ์์ด. ์ด๋ฒคํธ ๋ฃจํ๋ ์ด ํ์คํฌ๋ค์ ๋ฒ๊ฐ์๊ฐ๋ฉฐ ์คํํ๋ฉด์, ํจ์จ์ ์ผ๋ก ๋ฆฌ์์ค๋ฅผ ์ฌ์ฉํ๊ณ ์์ง. ๐
๐ก Pro Tip: asyncio๋ฅผ ๋ง์คํฐํ๋ฉด, ๋คํธ์ํฌ ํ๋ก๊ทธ๋๋ฐ์ด๋ ์น ์คํฌ๋ํ ๊ฐ์ I/O ๋ฐ์ด๋ ์์ ์์ ์์ฒญ๋ ์ฑ๋ฅ ํฅ์์ ๊ฒฝํํ ์ ์์ด. ์ด๋ฐ ์ค๋ ฅ์ ์ฌ๋ฅ๋ท์์ ๋ค ๊ฐ์น๋ฅผ ํ์ธต ๋ ๋์ฌ์ค ๊ฑฐ์ผ!
์, ์ด์ ๊ธฐ๋ณธ์ ์ธ asyncio ์ฌ์ฉ๋ฒ์ ์์์ผ๋, ์ข ๋ ๋ณต์กํ ์์ ๋ฅผ ์ดํด๋ณผ๊น? ๐ค
import asyncio
import random
async def fetch_data(url):
print(f"Fetching data from {url}")
await asyncio.sleep(random.uniform(0.5, 2.0)) # ์ค์ ๋คํธ์ํฌ ์์ฒญ์ ์๋ฎฌ๋ ์ด์
print(f"Finished fetching data from {url}")
return f"Data from {url}"
async def process_data(data):
print(f"Processing {data}")
await asyncio.sleep(0.5) # ๋ฐ์ดํฐ ์ฒ๋ฆฌ๋ฅผ ์๋ฎฌ๋ ์ด์
print(f"Finished processing {data}")
return f"Processed {data}"
async def main():
urls = ['http://example.com', 'http://example.org', 'http://example.net']
# ๋ฐ์ดํฐ ๊ฐ์ ธ์ค๊ธฐ
fetch_tasks = [fetch_data(url) for url in urls]
fetched_data = await asyncio.gather(*fetch_tasks)
# ๊ฐ์ ธ์จ ๋ฐ์ดํฐ ์ฒ๋ฆฌํ๊ธฐ
process_tasks = [process_data(data) for data in fetched_data]
processed_data = await asyncio.gather(*process_tasks)
for result in processed_data:
print(result)
asyncio.run(main())
์ด ์์ ๋ ์น ์คํฌ๋ํ์ด๋ API ์์ฒญ์ ํ ๋ ๋น๋๊ธฐ ํ๋ก๊ทธ๋๋ฐ์ด ์ผ๋ง๋ ์ ์ฉํ์ง ๋ณด์ฌ์ค. ์ฌ๋ฌ URL์์ ๋์์ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ค๊ณ , ๊ทธ ๋ฐ์ดํฐ๋ฅผ ์ฒ๋ฆฌํ๋ ๊ฑฐ์ผ. ๐
์ด๋ฐ ๋ฐฉ์์ผ๋ก ํ๋ก๊ทธ๋๋ฐํ๋ฉด, ๋คํธ์ํฌ ์ง์ฐ ์๊ฐ์ ํจ์จ์ ์ผ๋ก ํ์ฉํ ์ ์์ด. ํ URL์์ ๋ฐ์ดํฐ๋ฅผ ๊ธฐ๋ค๋ฆฌ๋ ๋์ ๋ค๋ฅธ URL์ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ฌ ์ ์์ผ๋๊น. ๐
๐จ ์ฃผ์์ฌํญ: ๋น๋๊ธฐ ํ๋ก๊ทธ๋๋ฐ์ ํ ๋๋ ํญ์ ์์ธ ์ฒ๋ฆฌ์ ์ ๊ฒฝ ์จ์ผ ํด. ๋คํธ์ํฌ ์ค๋ฅ๋ ํ์์์ ๊ฐ์ ๋ฌธ์ ๊ฐ ๋ฐ์ํ ์ ์๊ฑฐ๋ . try-except ๊ตฌ๋ฌธ์ ์ ์ ํ ์ฌ์ฉํ๋ ๊ฒ์ ์์ง ๋ง!
์, ์ด์ ๋น๋๊ธฐ ํ๋ก๊ทธ๋๋ฐ์ ๊ธฐ๋ณธ์ ์๊ฒ ๋์ด. ๊ทผ๋ฐ ์ฌ๊ธฐ์ ๋์ด ์๋์ผ. ๋น๋๊ธฐ ํ๋ก๊ทธ๋๋ฐ์๋ ๋ ๋ง์ ๊ฐ๋ ๊ณผ ํ ํฌ๋์ด ์์ด. ๋ค์ ์น์ ์์ ๋ ๊น์ด ํ๊ณ ๋ค์ด๋ณผ๊น? ์ค๋น๋๋? Let's go! ๐
๐ง ๋น๋๊ธฐ ํ๋ก๊ทธ๋๋ฐ์ ๊ณ ๊ธ ๊ฐ๋
์, ์ด์ ๋น๋๊ธฐ ํ๋ก๊ทธ๋๋ฐ์ ๋ ๊น์ ๋ถ๋ถ์ผ๋ก ๋ค์ด๊ฐ๋ณผ ๊ฑฐ์ผ. ์ค๋น๋๋? ์ฌํธํก ํ ๋ฒ ํ๊ณ ... ์์ํด๋ณผ๊น? ๐
1. ํ์คํฌ(Task)
ํ์คํฌ๋ ์ฝ๋ฃจํด์ ๊ฐ์ธ๋ ๊ฐ์ฒด์ผ. ์ฝ๋ฃจํด์ ์คํ์ ์ถ์ ํ๊ณ ๊ด๋ฆฌํ๋ ์ญํ ์ ํด. ํ์คํฌ๋ฅผ ์ฌ์ฉํ๋ฉด ์ฝ๋ฃจํด์ ์ํ๋ฅผ ํ์ธํ๊ฑฐ๋, ์ทจ์ํ ์ ์์ด.
import asyncio
async def my_coroutine():
print("Coroutine started")
await asyncio.sleep(1)
print("Coroutine finished")
async def main():
task = asyncio.create_task(my_coroutine())
print(f"Task created: {task}")
await task
print(f"Task completed: {task}")
asyncio.run(main())
์ด ์์ ์์ asyncio.create_task()
๋ฅผ ์ฌ์ฉํด ์ฝ๋ฃจํด์ ํ์คํฌ๋ก ๋ง๋ค์์ด. ํ์คํฌ๋ ์์ฑ๋์๋ง์ ์คํ์ ์์ํ์ง๋ง, await
๋ฅผ ์ฌ์ฉํด ์๋ฃ๋ ๋๊น์ง ๊ธฐ๋ค๋ฆด ์ ์์ด.
2. ํจ์ฒ(Future)
ํจ์ฒ๋ ๋น๋๊ธฐ ์ฐ์ฐ์ ์ต์ข ๊ฒฐ๊ณผ๋ฅผ ๋ํ๋ด๋ ๊ฐ์ฒด์ผ. ํ์คํฌ๋ ์ฌ์ค ํจ์ฒ์ ํ ์ข ๋ฅ๋ผ๊ณ ๋ณผ ์ ์์ด. ํจ์ฒ๋ ์์ง ์๋ฃ๋์ง ์์ ์ฐ์ฐ์ ํํํ๋๋ฐ ์ฌ์ฉ๋ผ.
import asyncio
async def set_after(fut, delay, value):
await asyncio.sleep(delay)
fut.set_result(value)
async def main():
loop = asyncio.get_running_loop()
fut = loop.create_future()
loop.create_task(set_after(fut, 1, '... World'))
print('Hello ...')
print(await fut)
asyncio.run(main())
์ด ์์ ์์๋ ํจ์ฒ๋ฅผ ๋ง๋ค๊ณ , ๋์ค์ ๊ทธ ๊ฒฐ๊ณผ๋ฅผ ์ค์ ํด. ๋ฉ์ธ ์ฝ๋ฃจํด์ ํจ์ฒ๊ฐ ์๋ฃ๋ ๋๊น์ง ๊ธฐ๋ค๋ ธ๋ค๊ฐ ๊ฒฐ๊ณผ๋ฅผ ์ถ๋ ฅํด.
3. ์ด๋ฒคํธ ๋ฃจํ(Event Loop)
์ด๋ฒคํธ ๋ฃจํ๋ ๋น๋๊ธฐ ํ๋ก๊ทธ๋จ์ ํต์ฌ์ด์ผ. ๋ชจ๋ ๋น๋๊ธฐ ์์ ์ ๊ด๋ฆฌํ๊ณ ์คํํ๋ ์ญํ ์ ํด. Python์ asyncio๋ ๊ธฐ๋ณธ์ ์ผ๋ก ๋จ์ผ ์ค๋ ๋ ์ด๋ฒคํธ ๋ฃจํ๋ฅผ ์ฌ์ฉํด.
์ ๊ทธ๋ฆผ์ ์ด๋ฒคํธ ๋ฃจํ์ ๋์ ์๋ฆฌ๋ฅผ ๋ณด์ฌ์ค. ์ด๋ฒคํธ ๋ฃจํ๋ ๊ณ์ํด์ ๋๋ฉด์ ์คํ ๊ฐ๋ฅํ ํ์คํฌ๋ฅผ ์ฐพ์ ์คํํด. ํ์คํฌ๊ฐ I/O ์์ ๊ฐ์ ๊ฑธ ๋ง๋๋ฉด ์ ์ ์ค๋จํ๊ณ ๋ค๋ฅธ ํ์คํฌ๋ก ๋์ด๊ฐ. ์ด๋ ๊ฒ ํด์ ํจ์จ์ ์ผ๋ก ๋ฆฌ์์ค๋ฅผ ์ฌ์ฉํ๋ ๊ฑฐ์ง. ๐
4. ๋์์ฑ๊ณผ ๋ณ๋ ฌ์ฑ
๋ง์ ์ฌ๋๋ค์ด ๋์์ฑ(Concurrency)๊ณผ ๋ณ๋ ฌ์ฑ(Parallelism)์ ํผ๋ํด. ํ์ง๋ง ์ด ๋์ ๋ค๋ฅธ ๊ฐ๋ ์ด์ผ.
- ๋์์ฑ: ์ฌ๋ฌ ์์ ์ ๋ฒ๊ฐ์๊ฐ๋ฉฐ ์คํํ๋ ๊ฒ. ํ ๋ฒ์ ํ๋์ ์์ ๋ง ์งํํ์ง๋ง, ๋น ๋ฅด๊ฒ ์ ํํด์ ๋ง์น ๋์์ ์คํ๋๋ ๊ฒ์ฒ๋ผ ๋ณด์ด๊ฒ ํด.
- ๋ณ๋ ฌ์ฑ: ์ค์ ๋ก ์ฌ๋ฌ ์์ ์ ๋์์ ์คํํ๋ ๊ฒ. ์ด๊ฑด ๋ฉํฐ์ฝ์ด ํ๋ก์ธ์์์ ๊ฐ๋ฅํด.
asyncio๋ ๊ธฐ๋ณธ์ ์ผ๋ก ๋์์ฑ์ ์ ๊ณตํด. ํ์ง๋ง Python์ ๋ฉํฐํ๋ก์ธ์ฑ๊ณผ ๊ฒฐํฉํ๋ฉด ๋ณ๋ ฌ์ฑ๋ ๋ฌ์ฑํ ์ ์์ด.
5. ๋น๋๊ธฐ ์ปจํ ์คํธ ๋งค๋์
Python์ with
๋ฌธ์ฒ๋ผ, asyncio๋ ๋น๋๊ธฐ ์ปจํ
์คํธ ๋งค๋์ ๋ฅผ ์ ๊ณตํด. ์ด๋ฅผ ํตํด ๋ฆฌ์์ค์ ํ๋๊ณผ ํด์ ๋ฅผ ๋น๋๊ธฐ์ ์ผ๋ก ๊ด๋ฆฌํ ์ ์์ด.
import asyncio
class AsyncContextManager:
async def __aenter__(self):
print("Entering the context")
await asyncio.sleep(1)
return self
async def __aexit__(self, exc_type, exc, tb):
print("Exiting the context")
await asyncio.sleep(1)
async def main():
async with AsyncContextManager() as manager:
print("Inside the context")
asyncio.run(main())
์ด ์์ ์์ AsyncContextManager
๋ ๋น๋๊ธฐ ์ปจํ
์คํธ ๋งค๋์ ์ผ. __aenter__
์ __aexit__
๋ฉ์๋๋ฅผ ๋น๋๊ธฐ์ ์ผ๋ก ์ ์ํด์ ๋ฆฌ์์ค์ ํ๋๊ณผ ํด์ ๋ฅผ ๋น๋๊ธฐ์ ์ผ๋ก ์ฒ๋ฆฌํ ์ ์์ด.
๐ก Pro Tip: ๋น๋๊ธฐ ์ปจํ ์คํธ ๋งค๋์ ๋ ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ฐ๊ฒฐ์ด๋ ๋คํธ์ํฌ ์์ผ ๊ฐ์ ๋ฆฌ์์ค๋ฅผ ๊ด๋ฆฌํ ๋ ํนํ ์ ์ฉํด. ์ฌ๋ฅ๋ท์์ ๋ฐฑ์๋ ๊ฐ๋ฐ์ ํ ๋ ์ด๋ฐ ๊ธฐ์ ์ ์ฌ์ฉํ๋ฉด ํจ์จ์ ์ธ ๋ฆฌ์์ค ๊ด๋ฆฌ๊ฐ ๊ฐ๋ฅํ ๊ฑฐ์ผ!
6. ๋น๋๊ธฐ ์ดํฐ๋ ์ดํฐ์ ์ ๋๋ ์ดํฐ
Python์ ์ดํฐ๋ ์ดํฐ์ ์ ๋๋ ์ดํฐ ๊ฐ๋ ์ ๋น๋๊ธฐ ์ธ๊ณ๋ก ํ์ฅํ ๊ฑฐ์ผ. ๋น๋๊ธฐ ์ดํฐ๋ ์ดํฐ๋ฅผ ์ฌ์ฉํ๋ฉด ๋๋์ ๋ฐ์ดํฐ๋ฅผ ๋น๋๊ธฐ์ ์ผ๋ก ์ฒ๋ฆฌํ ์ ์์ด.
import asyncio
class AsyncRange:
def __init__(self, start, stop):
self.start = start
self.stop = stop
def __aiter__(self):
return self
async def __anext__(self):
if self.start >= self.stop:
raise StopAsyncIteration
await asyncio.sleep(0.1) # ๊ฐ ํญ๋ชฉ ์ฌ์ด์ ์ฝ๊ฐ์ ์ง์ฐ์ ์ถ๊ฐ
self.start += 1
return self.start - 1
async def main():
async for i in AsyncRange(0, 5):
print(i)
asyncio.run(main())
์ด ์์ ์์ AsyncRange
๋ ๋น๋๊ธฐ ์ดํฐ๋ ์ดํฐ์ผ. __aiter__
์ __anext__
๋ฉ์๋๋ฅผ ๊ตฌํ ํด์ ๋น๋๊ธฐ์ ์ผ๋ก ๊ฐ์ ์์ฑํ๊ณ ์์ด. ์ด๋ฐ ๋ฐฉ์์ผ๋ก ๋๋์ ๋ฐ์ดํฐ๋ฅผ ํจ์จ์ ์ผ๋ก ์ฒ๋ฆฌํ ์ ์์ง.
7. ๋น๋๊ธฐ ์ปดํ๋ฆฌํจ์ ๊ณผ ์ ๋๋ ์ดํฐ ํํ์
Python์ ๋ฆฌ์คํธ ์ปดํ๋ฆฌํจ์ ๊ณผ ์ ๋๋ ์ดํฐ ํํ์์ ์ต์ํ์ง? asyncio๋ ์ด๋ฐ ํธ๋ฆฌํ ๋ฌธ๋ฒ์ ๋น๋๊ธฐ ์ธ๊ณ๋ก ๊ฐ์ ธ์์ด.
import asyncio
async def fetch_data(url):
await asyncio.sleep(1) # ๋คํธ์ํฌ ์์ฒญ์ ์๋ฎฌ๋ ์ด์
return f"Data from {url}"
async def main():
urls = ['http://example.com', 'http://example.org', 'http://example.net']
# ๋น๋๊ธฐ ์ปดํ๋ฆฌํจ์
results = [await fetch_data(url) for url in urls]
print(results)
# ๋น๋๊ธฐ ์ ๋๋ ์ดํฐ ํํ์
async for result in (fetch_data(url) for url in urls):
print(result)
asyncio.run(main())
์ด ์์ ์์ ๋น๋๊ธฐ ์ปดํ๋ฆฌํจ์ ๊ณผ ์ ๋๋ ์ดํฐ ํํ์์ ์ฌ์ฉํด ์ฌ๋ฌ URL์์ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ค๊ณ ์์ด. ์ด๋ฐ ๋ฐฉ์์ผ๋ก ์ฝ๋๋ฅผ ๊ฐ๊ฒฐํ๊ฒ ์ ์งํ๋ฉด์๋ ๋น๋๊ธฐ ์์ ์ ์ํํ ์ ์์ง.
8. ๋์์ฑ ์ ์ด
์ฌ๋ฌ ์ฝ๋ฃจํด์ด ๋์์ ์คํ๋ ๋, ๋๋ก๋ ์ด๋ค ์ฌ์ด์ ์คํ ์์๋ ๋์ ์ ๊ทผ์ ์ ์ดํด์ผ ํ ํ์๊ฐ ์์ด. asyncio๋ ์ด๋ฅผ ์ํ ์ฌ๋ฌ ๋๊ตฌ๋ฅผ ์ ๊ณตํด.
- Lock: ํ ๋ฒ์ ํ๋์ ์ฝ๋ฃจํด๋ง ํน์ ์ฝ๋ ๋ธ๋ก์ ์ ๊ทผํ ์ ์๋๋ก ํด.
- Semaphore: ๋์์ ์คํ๋ ์ ์๋ ์ฝ๋ฃจํด์ ์๋ฅผ ์ ํํด.
- Event: ํ ์ฝ๋ฃจํด์ด ๋ค๋ฅธ ์ฝ๋ฃจํด์๊ฒ ํน์ ์ด๋ฒคํธ๊ฐ ๋ฐ์ํ์์ ์๋ฆด ์ ์๊ฒ ํด.
- Condition: ๋ณต์กํ ๋๊ธฐํ ์๋๋ฆฌ์ค๋ฅผ ์ฒ๋ฆฌํ ์ ์๊ฒ ํด.
import asyncio
async def worker(semaphore, name):
async with semaphore:
print(f"{name} is working")
await asyncio.sleep(1)
print(f"{name} is done")
async def main():
semaphore = asyncio.Semaphore(2) # ์ต๋ 2๊ฐ์ ์์
๋ง ๋์ ์คํ
workers = [asyncio.create_task(worker(semaphore, f"Worker {i}")) for i in range(5)]
await asyncio.gather(*workers)
asyncio.run(main())
์ด ์์ ์์๋ ์ธ๋งํฌ์ด๋ฅผ ์ฌ์ฉํด ๋์์ ์คํ๋๋ ์์ ์ ์๋ฅผ 2๊ฐ๋ก ์ ํํ๊ณ ์์ด. ์ด๋ฐ ๋ฐฉ์์ผ๋ก ๋ฆฌ์์ค ์ฌ์ฉ์ ์ ์ดํ๊ณ ๊ณผ๋ถํ๋ฅผ ๋ฐฉ์งํ ์ ์์ง.
์ ๊ทธ๋ฆผ์ ๋์์ฑ ์ ์ด์ ์ฃผ์ ๊ฐ๋ ๋ค์ ๋ณด์ฌ์ค. Lock, Semaphore, Event ๋ฑ์ ๋๊ตฌ๋ค์ด ์ด๋ป๊ฒ ๋น๋๊ธฐ ํ์คํฌ๋ค์ ์กฐ์จํ๋์ง ๋ณผ ์ ์์ด. ์ด๋ฐ ๋๊ตฌ๋ค์ ์ ์ ํ ์ฌ์ฉํ๋ฉด ๋ณต์กํ ๋น๋๊ธฐ ์์คํ ๋ ์์ ์ ์ผ๋ก ๊ด๋ฆฌํ ์ ์์ง. ๐
๐จ ์ฃผ์์ฌํญ: ๋์์ฑ ์ ์ด ๋๊ตฌ๋ฅผ ์ฌ์ฉํ ๋๋ ๋ฐ๋๋ฝ(deadlock)์ ์ฃผ์ํด์ผ ํด. ์ฌ๋ฌ ๊ฐ์ ๋ฝ์ ์ฌ์ฉํ ๋ ํนํ ์กฐ์ฌํด์ผ ํ์ง. ํญ์ ๋์ผํ ์์๋ก ๋ฝ์ ํ๋ํ๊ณ ํด์ ํ๋ ๊ฒ์ด ์ข์.
9. ๋น๋๊ธฐ ์คํธ๋ฆผ
๋๋์ ๋ฐ์ดํฐ๋ฅผ ์ฒ๋ฆฌํ ๋, ๋ชจ๋ ๋ฐ์ดํฐ๋ฅผ ๋ฉ๋ชจ๋ฆฌ์ ํ ๋ฒ์ ๋ก๋ํ๋ ๊ฒ์ ๋นํจ์จ์ ์ผ ์ ์์ด. ๋น๋๊ธฐ ์คํธ๋ฆผ์ ์ฌ์ฉํ๋ฉด ๋ฐ์ดํฐ๋ฅผ ์ฒญํฌ(chunk) ๋จ์๋ก ๋น๋๊ธฐ์ ์ผ๋ก ์ฒ๋ฆฌํ ์ ์์ด.
import asyncio
async def data_source():
for i in range(10):
await asyncio.sleep(0.5) # ๋ฐ์ดํฐ ์์ฑ ์๊ฐ์ ์๋ฎฌ๋ ์ด์
yield f"data {i}"
async def process_stream():
async for data in data_source():
print(f"Processing {data}")
await asyncio.sleep(0.1) # ๋ฐ์ดํฐ ์ฒ๋ฆฌ ์๊ฐ์ ์๋ฎฌ๋ ์ด์
asyncio.run(process_stream())
์ด ์์ ์์ data_source
ํจ์๋ ๋น๋๊ธฐ ์ ๋๋ ์ดํฐ๋ก, ๋ฐ์ดํฐ๋ฅผ ์คํธ๋ฆผ ํํ๋ก ์์ฑํด. process_stream
ํจ์๋ ์ด ์คํธ๋ฆผ์ ๋น๋๊ธฐ์ ์ผ๋ก ์ฒ๋ฆฌํ๊ณ ์์ด. ์ด๋ฐ ๋ฐฉ์์ผ๋ก ๋์ฉ๋ ๋ฐ์ดํฐ๋ฅผ ํจ์จ์ ์ผ๋ก ์ฒ๋ฆฌํ ์ ์์ง.
10. ๋น๋๊ธฐ ํ ์คํ
๋น๋๊ธฐ ์ฝ๋๋ฅผ ํ ์คํธํ๋ ๊ฒ์ ๋๊ธฐ ์ฝ๋๋ฅผ ํ ์คํธํ๋ ๊ฒ๋ณด๋ค ์กฐ๊ธ ๋ ๋ณต์กํ ์ ์์ด. ํ์ง๋ง Python์ unittest ๋ชจ๋๊ณผ asyncio๋ฅผ ๊ฒฐํฉํ๋ฉด ํจ๊ณผ์ ์ผ๋ก ๋น๋๊ธฐ ์ฝ๋๋ฅผ ํ ์คํธํ ์ ์์ด.
import asyncio
import unittest
async def async_sum(a, b):
await asyncio.sleep(0.1) # ๋น๋๊ธฐ ์์
์ ์๋ฎฌ๋ ์ด์
return a + b
class TestAsyncSum(unittest.TestCase):
def test_async_sum(self):
result = asyncio.run(async_sum(1, 2))
self.assertEqual(result, 3)
async def async_test_sum(self):
result = await async_sum(1, 2)
self.assertEqual(result, 3)
def test_async_sum_with_loop(self):
async def run_test():
return await self.async_test_sum()
asyncio.run(run_test())
if __name__ == '__main__':
unittest.main()
์ด ์์ ์์๋ ์ธ ๊ฐ์ง ๋ฐฉ๋ฒ์ผ๋ก ๋น๋๊ธฐ ํจ์๋ฅผ ํ
์คํธํ๊ณ ์์ด. asyncio.run()
์ ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ, ๋น๋๊ธฐ ํ
์คํธ ๋ฉ์๋๋ฅผ ์ ์ํ๋ ๋ฐฉ๋ฒ, ๊ทธ๋ฆฌ๊ณ ์ด๋ฒคํธ ๋ฃจํ ๋ด์์ ๋น๋๊ธฐ ํ
์คํธ๋ฅผ ์คํํ๋ ๋ฐฉ๋ฒ์ ๋ณด์ฌ์ฃผ๊ณ ์์ง.
๐ก Pro Tip: ๋น๋๊ธฐ ์ฝ๋๋ฅผ ํ ์คํธํ ๋๋ mock ๊ฐ์ฒด๋ฅผ ์ฌ์ฉํด ์ธ๋ถ ์์กด์ฑ(์: ๋ฐ์ดํฐ๋ฒ ์ด์ค, ๋คํธ์ํฌ ์์ฒญ)์ ๋์ฒดํ๋ ๊ฒ์ด ์ข์. ์ด๋ ๊ฒ ํ๋ฉด ํ ์คํธ ์คํ ์๊ฐ์ ์ค์ด๊ณ ๋ ์์ ์ ์ธ ํ ์คํธ๋ฅผ ์์ฑํ ์ ์์ด. ์ฌ๋ฅ๋ท์์ ํ๋ก์ ํธ๋ฅผ ์งํํ ๋ ์ด๋ฐ ํ ์คํ ๊ธฐ๋ฒ์ ์ ์ฉํ๋ฉด ์ฝ๋์ ํ์ง์ ํฌ๊ฒ ๋์ผ ์ ์์ ๊ฑฐ์ผ!
์, ์ด์ ์ฐ๋ฆฌ๋ Python์ ๋น๋๊ธฐ ํ๋ก๊ทธ๋๋ฐ์ ๋ํด ๊ฝค ๊น์ด ์๊ฒ ์ดํด๋ดค์ด. ์ด ๊ฐ๋ ๋ค์ ์ ์ดํดํ๊ณ ์ ์ฉํ๋ค๋ฉด, ๋คํธ์ํฌ ํ๋ก๊ทธ๋๋ฐ, ์น ๊ฐ๋ฐ, ๋ฐ์ดํฐ ์ฒ๋ฆฌ ๋ฑ ๋ค์ํ ๋ถ์ผ์์ ํจ์ฌ ๋ ํจ์จ์ ์ด๊ณ ๊ฐ๋ ฅํ ํ๋ก๊ทธ๋จ์ ๋ง๋ค ์ ์์ ๊ฑฐ์ผ. ๐
๋น๋๊ธฐ ํ๋ก๊ทธ๋๋ฐ์ ์ฒ์์๋ ์กฐ๊ธ ์ด๋ ต๊ฒ ๋๊ปด์ง ์ ์์ด. ํ์ง๋ง ๊ณ์ ์ฐ์ตํ๊ณ ์ค์ ํ๋ก์ ํธ์ ์ ์ฉํด ๋ณด๋ฉด, ์ ์ ๋ ์์ฐ์ค๋ฝ๊ฒ ์ฌ์ฉํ ์ ์๊ฒ ๋ ๊ฑฐ์ผ. ๊ทธ๋ฆฌ๊ณ ๊ทธ ๊ณผ์ ์์ ํ๋ก๊ทธ๋๋ฐ์ ์๋ก์ด ์ฐจ์์ ๊ฒฝํํ๊ฒ ๋ ๊ฑฐ๋ผ๊ณ ํ์ ํด!
์ฌ๊ธฐ๊น์ง Python์ ๋น๋๊ธฐ ํ๋ก๊ทธ๋๋ฐ์ ๋ํ ๊น์ด ์๋ ์ค๋ช ์ด์์ด. ์ด ์ง์์ ๋ฐํ์ผ๋ก ๋ ํจ์จ์ ์ด๊ณ ๊ฐ๋ ฅํ ํ๋ก๊ทธ๋จ์ ๋ง๋ค ์ ์๊ธฐ๋ฅผ ๋ฐ๋ผ! ํ์ดํ ! ๐๐
- ์ง์์ธ์ ์ฒ - ์ง์ ์ฌ์ฐ๊ถ ๋ณดํธ ๊ณ ์ง
์ง์ ์ฌ์ฐ๊ถ ๋ณดํธ ๊ณ ์ง
- ์ ์๊ถ ๋ฐ ์์ ๊ถ: ๋ณธ ์ปจํ ์ธ ๋ ์ฌ๋ฅ๋ท์ ๋ ์ AI ๊ธฐ์ ๋ก ์์ฑ๋์์ผ๋ฉฐ, ๋ํ๋ฏผ๊ตญ ์ ์๊ถ๋ฒ ๋ฐ ๊ตญ์ ์ ์๊ถ ํ์ฝ์ ์ํด ๋ณดํธ๋ฉ๋๋ค.
- AI ์์ฑ ์ปจํ ์ธ ์ ๋ฒ์ ์ง์: ๋ณธ AI ์์ฑ ์ปจํ ์ธ ๋ ์ฌ๋ฅ๋ท์ ์ง์ ์ฐฝ์๋ฌผ๋ก ์ธ์ ๋๋ฉฐ, ๊ด๋ จ ๋ฒ๊ท์ ๋ฐ๋ผ ์ ์๊ถ ๋ณดํธ๋ฅผ ๋ฐ์ต๋๋ค.
- ์ฌ์ฉ ์ ํ: ์ฌ๋ฅ๋ท์ ๋ช ์์ ์๋ฉด ๋์ ์์ด ๋ณธ ์ปจํ ์ธ ๋ฅผ ๋ณต์ , ์์ , ๋ฐฐํฌ, ๋๋ ์์ ์ ์ผ๋ก ํ์ฉํ๋ ํ์๋ ์๊ฒฉํ ๊ธ์ง๋ฉ๋๋ค.
- ๋ฐ์ดํฐ ์์ง ๊ธ์ง: ๋ณธ ์ปจํ ์ธ ์ ๋ํ ๋ฌด๋จ ์คํฌ๋ํ, ํฌ๋กค๋ง, ๋ฐ ์๋ํ๋ ๋ฐ์ดํฐ ์์ง์ ๋ฒ์ ์ ์ฌ์ ๋์์ด ๋ฉ๋๋ค.
- AI ํ์ต ์ ํ: ์ฌ๋ฅ๋ท์ AI ์์ฑ ์ปจํ ์ธ ๋ฅผ ํ AI ๋ชจ๋ธ ํ์ต์ ๋ฌด๋จ ์ฌ์ฉํ๋ ํ์๋ ๊ธ์ง๋๋ฉฐ, ์ด๋ ์ง์ ์ฌ์ฐ๊ถ ์นจํด๋ก ๊ฐ์ฃผ๋ฉ๋๋ค.
์ฌ๋ฅ๋ท์ ์ต์ AI ๊ธฐ์ ๊ณผ ๋ฒ๋ฅ ์ ๊ธฐ๋ฐํ์ฌ ์์ฌ์ ์ง์ ์ฌ์ฐ๊ถ์ ์ ๊ทน์ ์ผ๋ก ๋ณดํธํ๋ฉฐ,
๋ฌด๋จ ์ฌ์ฉ ๋ฐ ์นจํด ํ์์ ๋ํด ๋ฒ์ ๋์์ ํ ๊ถ๋ฆฌ๋ฅผ ๋ณด์ ํฉ๋๋ค.
ยฉ 2025 ์ฌ๋ฅ๋ท | All rights reserved.
๋๊ธ 0๊ฐ