๊ธ๋ก๋ฒ ์ธํฐํ๋ฆฌํฐ ๋ฝ(GIL)์ ๋ํ ์ฌ์ธต ๋ถ์, Python๊ณผ ๊ฐ์ ํ๋ก๊ทธ๋๋ฐ ์ธ์ด์ ๋์์ฑ ์ํฅ ๋ฐ ์ ํ ์ํ ์ ๋ต.
๊ธ๋ก๋ฒ ์ธํฐํ๋ฆฌํฐ ๋ฝ (GIL): ๋์์ฑ ์ ํ์ ๋ํ ํฌ๊ด์ ์ธ ๋ถ์
๊ธ๋ก๋ฒ ์ธํฐํ๋ฆฌํฐ ๋ฝ(GIL)์ ๋ช๋ช ์ธ๊ธฐ ํ๋ก๊ทธ๋๋ฐ ์ธ์ด, ํนํ Python๊ณผ Ruby์ ์ํคํ ์ฒ์์ ๋ ผ์์ ์ฌ์ง๊ฐ ์์ง๋ง ์ค์ํ ์ธก๋ฉด์ ๋๋ค. ์ด๋ ์ด๋ฌํ ์ธ์ด์ ๋ด๋ถ ์๋์ ๋จ์ํํ๋ ๋์์ ํนํ CPU ๋ฐ์ด๋ ์์ ์์ ์ง์ ํ ๋ณ๋ ฌ ์ฒ๋ฆฌ์ ์ ํ์ ๋ก๋๋ค. ์ด ๊ธฐ์ฌ์์๋ GIL, ๋์์ฑ์ ๋ฏธ์น๋ ์ํฅ ๋ฐ ์ํฅ์ ์ํํ๊ธฐ ์ํ ์ ๋ต์ ๋ํ ํฌ๊ด์ ์ธ ๋ถ์์ ์ ๊ณตํฉ๋๋ค.
๊ธ๋ก๋ฒ ์ธํฐํ๋ฆฌํฐ ๋ฝ (GIL)์ด๋?
ํต์ฌ์ ์ผ๋ก GIL์ ํ ๋ฒ์ ํ๋์ ์ค๋ ๋๋ง Python ์ธํฐํ๋ฆฌํฐ๋ฅผ ์ ์ดํ ์ ์๋๋ก ํ๋ ๋ฎคํ ์ค(์ํธ ๋ฐฐํ์ ์ ๊ธ)์ ๋๋ค. ์ฆ, ๋ฉํฐ ์ฝ์ด ํ๋ก์ธ์์์๋ ํ ๋ฒ์ ํ๋์ ์ค๋ ๋๋ง Python ๋ฐ์ดํธ ์ฝ๋๋ฅผ ์คํํ ์ ์์ต๋๋ค. GIL์ ๋ฉ๋ชจ๋ฆฌ ๊ด๋ฆฌ๋ฅผ ๋จ์ํํ๊ณ ๋จ์ผ ์ค๋ ๋ ํ๋ก๊ทธ๋จ์ ์ฑ๋ฅ์ ํฅ์์ํค๊ธฐ ์ํด ๋์ ๋์์ต๋๋ค. ๊ทธ๋ฌ๋ ์ฌ๋ฌ CPU ์ฝ์ด๋ฅผ ํ์ฉํ๋ ค๋ ๋ฉํฐ ์ค๋ ๋ ์ ํ๋ฆฌ์ผ์ด์ ์ ์ฌ๊ฐํ ๋ณ๋ชฉ ํ์์ ์ ์ํฉ๋๋ค.
๋ฐ์ ๊ตญ์ ๊ณตํญ์ ์์ํด ๋ณด์ธ์. GIL์ ๋จ์ผ ๋ณด์ ๊ฒ๋ฌธ์์ ๊ฐ์ต๋๋ค. ์ฌ๋ฌ ๊ฐ์ ๊ฒ์ดํธ์ ์ด๋ฅ ์ค๋น๊ฐ ๋ ๋นํ๊ธฐ(CPU ์ฝ์ด ํํ)๊ฐ ์๋๋ผ๋ ์น๊ฐ(์ค๋ ๋)์ ํ ๋ฒ์ ํ๋์ฉ ํด๋น ๋จ์ผ ๊ฒ๋ฌธ์๋ฅผ ํต๊ณผํด์ผ ํฉ๋๋ค. ์ด๊ฒ์ ๋ณ๋ชฉ ํ์์ ๋ง๋ค๊ณ ์ ์ฒด ํ๋ก์ธ์ค์ ์๋๋ฅผ ๋ฆ์ถฅ๋๋ค.
GIL์ ์ ๋์ ๋์์ต๋๊น?
GIL์ ์ฃผ๋ก ๋ ๊ฐ์ง ์ฃผ์ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด ๋์ ๋์์ต๋๋ค.
- ๋ฉ๋ชจ๋ฆฌ ๊ด๋ฆฌ: ์ด๊ธฐ ๋ฒ์ ์ Python์ ๋ฉ๋ชจ๋ฆฌ ๊ด๋ฆฌ์ ์ฐธ์กฐ ๊ณ์๋ฅผ ์ฌ์ฉํ์ต๋๋ค. GIL์ด ์์ผ๋ฉด ์ค๋ ๋ ์์ ํ ๋ฐฉ์์ผ๋ก ์ด๋ฌํ ์ฐธ์กฐ ๊ณ์๋ฅผ ๊ด๋ฆฌํ๋ ๊ฒ์ด ๋ณต์กํ๊ณ ๊ณ์ฐ ๋น์ฉ์ด ๋ง์ด ๋ค์ด ๋ ์ด์ค ์ปจ๋์ ๋ฐ ๋ฉ๋ชจ๋ฆฌ ์์์ด ๋ฐ์ํ ์ ์์ต๋๋ค.
- ๊ฐ์ํ๋ C ํ์ฅ: GIL์ C ํ์ฅ์ Python๊ณผ ํตํฉํ๋ ๊ฒ์ ๋ ์ฝ๊ฒ ๋ง๋ค์์ต๋๋ค. ํนํ ๊ณผํ ์ปดํจํ (NumPy ๋ฑ)๊ณผ ๊ด๋ จ๋ ๋ง์ Python ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ ์ฑ๋ฅ์ ์ํด C ์ฝ๋์ ํฌ๊ฒ ์์กดํฉ๋๋ค. GIL์ Python์์ C ์ฝ๋๋ฅผ ํธ์ถํ ๋ ์ค๋ ๋ ์์ ์ฑ์ ๋ณด์ฅํ๋ ๊ฐ๋จํ ๋ฐฉ๋ฒ์ ์ ๊ณตํ์ต๋๋ค.
GIL์ด ๋์์ฑ์ ๋ฏธ์น๋ ์ํฅ
GIL์ ์ฃผ๋ก CPU ๋ฐ์ด๋ ์์ ์ ์ํฅ์ ๋ฏธ์นฉ๋๋ค. CPU ๋ฐ์ด๋ ์์ ์ I/O ์์ (์: ๋คํธ์ํฌ ์์ฒญ, ๋์คํฌ ์ฝ๊ธฐ)์ ๊ธฐ๋ค๋ฆฌ๋ ๋์ ๋๋ถ๋ถ์ ์๊ฐ์ ๊ณ์ฐ์ ์ํํ๋ ์์ ์ ๋๋ค. ์๋ก๋ ์ด๋ฏธ์ง ์ฒ๋ฆฌ, ์์น ๊ณ์ฐ ๋ฐ ๋ณต์กํ ๋ฐ์ดํฐ ๋ณํ์ด ์์ต๋๋ค. CPU ๋ฐ์ด๋ ์์ ์ ๊ฒฝ์ฐ GIL์ ํ ๋ฒ์ ํ๋์ ์ค๋ ๋๋ง Python ์ฝ๋๋ฅผ ํ๋ฐํ๊ฒ ์คํํ ์ ์์ผ๋ฏ๋ก ์ง์ ํ ๋ณ๋ ฌ ์ฒ๋ฆฌ๋ฅผ ๋ฐฉ์งํฉ๋๋ค. ์ด๋ก ์ธํด ๋ฉํฐ ์ฝ์ด ์์คํ ์์ ์ฑ๋ฅ์ด ์ ํ๋ ์ ์์ต๋๋ค.
๊ทธ๋ฌ๋ GIL์ I/O ๋ฐ์ด๋ ์์ ์ ๋ฏธ์น๋ ์ํฅ์ด ์ ์ต๋๋ค. I/O ๋ฐ์ด๋ ์์ ์ ์ธ๋ถ ์์ ์ด ์๋ฃ๋ ๋๊น์ง ๋๋ถ๋ถ์ ์๊ฐ์ ๊ธฐ๋ค๋ฆฝ๋๋ค. ํ๋์ ์ค๋ ๋๊ฐ I/O๋ฅผ ๊ธฐ๋ค๋ฆฌ๋ ๋์ GIL์ด ํด์ ๋์ด ๋ค๋ฅธ ์ค๋ ๋๊ฐ ์คํ๋ ์ ์์ต๋๋ค. ๋ฐ๋ผ์ ์ฃผ๋ก I/O ๋ฐ์ด๋์ธ ๋ฉํฐ ์ค๋ ๋ ์ ํ๋ฆฌ์ผ์ด์ ์ GIL์ด ์์ด๋ ๋์์ฑ์ ์ด์ ์ ๋๋ฆด ์ ์์ต๋๋ค.
์๋ฅผ ๋ค์ด, ์ฌ๋ฌ ํด๋ผ์ด์ธํธ ์์ฒญ์ ์ฒ๋ฆฌํ๋ ์น ์๋ฒ๋ฅผ ์๊ฐํด ๋ณด์ธ์. ๊ฐ ์์ฒญ์๋ ๋ฐ์ดํฐ๋ฒ ์ด์ค์์ ๋ฐ์ดํฐ๋ฅผ ์ฝ๊ณ , ์ธ๋ถ API ํธ์ถ์ ํ๊ณ , ํ์ผ์ ๋ฐ์ดํฐ๋ฅผ ์ฐ๋ ์์ ์ด ํฌํจ๋ ์ ์์ต๋๋ค. ์ด๋ฌํ I/O ์์ ์ GIL์ด ํด์ ๋์ด ๋ค๋ฅธ ์ค๋ ๋๊ฐ ๋ค๋ฅธ ์์ฒญ์ ๋์์ ์ฒ๋ฆฌํ ์ ์๋๋ก ํฉ๋๋ค. ๋ฐ๋๋ก, ๋๊ท๋ชจ ๋ฐ์ดํฐ ์ธํธ์ ๋ํด ๋ณต์กํ ์ํ์ ๊ณ์ฐ์ ์ํํ๋ ํ๋ก๊ทธ๋จ์ GIL์ ์ํด ์ฌ๊ฐํ๊ฒ ์ ํ๋ฉ๋๋ค.
CPU ๋ฐ์ด๋ ์์ ๊ณผ I/O ๋ฐ์ด๋ ์์ ์ดํด
GIL์ ์ํฅ์ ์ดํดํ๊ณ ์ ์ ํ ๋์์ฑ ์ ๋ต์ ์ ํํ๋ ค๋ฉด CPU ๋ฐ์ด๋ ์์ ๊ณผ I/O ๋ฐ์ด๋ ์์ ์ ๊ตฌ๋ณํ๋ ๊ฒ์ด ์ค์ํฉ๋๋ค.
CPU ๋ฐ์ด๋ ์์
- ์ ์: CPU๊ฐ ๊ณ์ฐ์ ์ํํ๊ฑฐ๋ ๋ฐ์ดํฐ๋ฅผ ์ฒ๋ฆฌํ๋ ๋ฐ ๋๋ถ๋ถ์ ์๊ฐ์ ์๋นํ๋ ์์ .
- ํน์ง: ๋์ CPU ์ฌ์ฉ๋ฅ , ์ธ๋ถ ์์ ๋๊ธฐ ์ต์ํ.
- ์: ์ด๋ฏธ์ง ์ฒ๋ฆฌ, ๋น๋์ค ์ธ์ฝ๋ฉ, ์์น ์๋ฎฌ๋ ์ด์ , ์ํธํ ์์ .
- GIL ์ํฅ: ์ฌ๋ฌ ์ฝ์ด์์ ๋ณ๋ ฌ๋ก Python ์ฝ๋๋ฅผ ์คํํ ์ ์์ด ์ฌ๊ฐํ ์ฑ๋ฅ ๋ณ๋ชฉ ํ์.
I/O ๋ฐ์ด๋ ์์
- ์ ์: ํ๋ก๊ทธ๋จ์ด ์ธ๋ถ ์์ ์ด ์๋ฃ๋ ๋๊น์ง ๋๋ถ๋ถ์ ์๊ฐ์ ๊ธฐ๋ค๋ฆฌ๋ ์์ .
- ํน์ง: ๋ฎ์ CPU ์ฌ์ฉ๋ฅ , I/O ์์ (๋คํธ์ํฌ, ๋์คํฌ ๋ฑ) ๋๊ธฐ ๋น๋ฒ.
- ์: ์น ์๋ฒ, ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ํธ ์์ฉ, ํ์ผ I/O, ๋คํธ์ํฌ ํต์ .
- GIL ์ํฅ: I/O๋ฅผ ๊ธฐ๋ค๋ฆฌ๋ ๋์ GIL์ด ํด์ ๋์ด ๋ค๋ฅธ ์ค๋ ๋๊ฐ ์คํ๋๋ฏ๋ก ์ํฅ์ด ๋ ์ค์ํฉ๋๋ค.
GIL ์ ํ ์ํ ์ ๋ต
GIL์ด ๋ถ๊ณผํ๋ ์ ํ์๋ ๋ถ๊ตฌํ๊ณ Python ๋ฐ ๊ธฐํ GIL์ ์ํฅ์ ๋ฐ๋ ์ธ์ด์์ ๋์์ฑ ๋ฐ ๋ณ๋ ฌ์ฑ์ ๋ฌ์ฑํ๊ธฐ ์ํด ์ฌ๋ฌ ๊ฐ์ง ์ ๋ต์ ์ฌ์ฉํ ์ ์์ต๋๋ค.
1. ๋ฉํฐํ๋ก์ธ์ฑ
๋ฉํฐํ๋ก์ธ์ฑ์ ์์ฒด Python ์ธํฐํ๋ฆฌํฐ์ ๋ฉ๋ชจ๋ฆฌ ๊ณต๊ฐ์ ๊ฐ์ง ์ฌ๋ฌ ๊ฐ์ ๋ณ๋ ํ๋ก์ธ์ค๋ฅผ ์์ฑํ๋ ๊ฒ์ ํฌํจํฉ๋๋ค. ์ด๋ ๊ฒ ํ๋ฉด GIL์ ์์ ํ ์ฐํํ์ฌ ๋ฉํฐ ์ฝ์ด ์์คํ ์์ ์ง์ ํ ๋ณ๋ ฌ ์ฒ๋ฆฌ๊ฐ ๊ฐ๋ฅํฉ๋๋ค. Python์ `multiprocessing` ๋ชจ๋์ ํ๋ก์ธ์ค๋ฅผ ์์ฑํ๊ณ ๊ด๋ฆฌํ๋ ๊ฐ๋จํ ๋ฐฉ๋ฒ์ ์ ๊ณตํฉ๋๋ค.
์:
import multiprocessing
def worker(num):
print(f"Worker {num}: Starting")
# Perform some CPU-bound task
result = sum(i * i for i in range(1000000))
print(f"Worker {num}: Finished, Result = {result}")
if __name__ == '__main__':
processes = []
for i in range(4):
p = multiprocessing.Process(target=worker, args=(i,))
processes.append(p)
p.start()
for p in processes:
p.join()
print("All workers finished")
์ฅ์ :
- ๋ฉํฐ ์ฝ์ด ์์คํ ์์ ์ง์ ํ ๋ณ๋ ฌ ์ฒ๋ฆฌ.
- GIL ์ ํ์ ์ฐํํฉ๋๋ค.
- CPU ๋ฐ์ด๋ ์์ ์ ์ ํฉํฉ๋๋ค.
๋จ์ :
- ๋ณ๋ ๋ฉ๋ชจ๋ฆฌ ๊ณต๊ฐ์ผ๋ก ์ธํด ๋ ๋์ ๋ฉ๋ชจ๋ฆฌ ์ค๋ฒํค๋.
- ํ๋ก์ธ์ค ๊ฐ ํต์ ์ ์ค๋ ๋ ๊ฐ ํต์ ๋ณด๋ค ๋ ๋ณต์กํ ์ ์์ต๋๋ค.
- ํ๋ก์ธ์ค ๊ฐ ๋ฐ์ดํฐ ์ง๋ ฌํ ๋ฐ ์ญ์ง๋ ฌํ๋ ์ค๋ฒํค๋๋ฅผ ์ถ๊ฐํ ์ ์์ต๋๋ค.
2. ๋น๋๊ธฐ ํ๋ก๊ทธ๋๋ฐ (asyncio)
๋น๋๊ธฐ ํ๋ก๊ทธ๋๋ฐ์ ํตํด ๋จ์ผ ์ค๋ ๋๋ I/O ์์ ์ ๊ธฐ๋ค๋ฆฌ๋ ๋์ ์ฌ๋ฌ ์์ ์ ์ ํํ์ฌ ์ฌ๋ฌ ๋์ ์์ ์ ์ฒ๋ฆฌํ ์ ์์ต๋๋ค. Python์ `asyncio` ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ ์ฝ๋ฃจํด๊ณผ ์ด๋ฒคํธ ๋ฃจํ๋ฅผ ์ฌ์ฉํ์ฌ ๋น๋๊ธฐ ์ฝ๋๋ฅผ ์์ฑํ๊ธฐ ์ํ ํ๋ ์์ํฌ๋ฅผ ์ ๊ณตํฉ๋๋ค.
์:
import asyncio
import aiohttp
async def fetch_url(url):
async with aiohttp.ClientSession() as session:
async with session.get(url) as response:
return await response.text()
async def main():
urls = [
"https://www.example.com",
"https://www.google.com",
"https://www.python.org"
]
tasks = [fetch_url(url) for url in urls]
results = await asyncio.gather(*tasks)
for i, result in enumerate(results):
print(f"Content from {urls[i]}: {result[:50]}...") # Print the first 50 characters
if __name__ == '__main__':
asyncio.run(main())
์ฅ์ :
- I/O ๋ฐ์ด๋ ์์ ์ ํจ์จ์ ์ธ ์ฒ๋ฆฌ.
- ๋ฉํฐํ๋ก์ธ์ฑ์ ๋นํด ๋ฎ์ ๋ฉ๋ชจ๋ฆฌ ์ค๋ฒํค๋.
- ๋คํธ์ํฌ ํ๋ก๊ทธ๋๋ฐ, ์น ์๋ฒ ๋ฐ ๊ธฐํ ๋น๋๊ธฐ ์ ํ๋ฆฌ์ผ์ด์ ์ ์ ํฉํฉ๋๋ค.
๋จ์ :
- CPU ๋ฐ์ด๋ ์์ ์ ๋ํ ์ง์ ํ ๋ณ๋ ฌ ์ฒ๋ฆฌ๋ฅผ ์ ๊ณตํ์ง ์์ต๋๋ค.
- ์ด๋ฒคํธ ๋ฃจํ๋ฅผ ์ค๋จ์ํฌ ์ ์๋ ๋ธ๋กํน ์์ ์ ํผํ๊ธฐ ์ํด ์ ์คํ ์ค๊ณ๊ฐ ํ์ํฉ๋๋ค.
- ๊ธฐ์กด ๋ฉํฐ์ค๋ ๋ฉ๋ณด๋ค ๊ตฌํ์ด ๋ ๋ณต์กํ ์ ์์ต๋๋ค.
3. concurrent.futures
`concurrent.futures` ๋ชจ๋์ ์ค๋ ๋ ๋๋ ํ๋ก์ธ์ค๋ฅผ ์ฌ์ฉํ์ฌ ๋น๋๊ธฐ์ ์ผ๋ก ํธ์ถ ๊ฐ๋ฅํ ํญ๋ชฉ์ ์คํํ๊ธฐ ์ํ ์์ ์์ค ์ธํฐํ์ด์ค๋ฅผ ์ ๊ณตํฉ๋๋ค. ์์ ์ ์์ ์ ํ์ ์ฝ๊ฒ ์ ์ถํ๊ณ ํฅํ ๊ฒฐ๊ณผ๋ฅผ ๊ฒ์ํ ์ ์์ต๋๋ค.
์์(์ค๋ ๋ ๊ธฐ๋ฐ):
from concurrent.futures import ThreadPoolExecutor
import time
def task(n):
print(f"Task {n}: Starting")
time.sleep(1) # Simulate some work
print(f"Task {n}: Finished")
return n * 2
if __name__ == '__main__':
with ThreadPoolExecutor(max_workers=3) as executor:
futures = [executor.submit(task, i) for i in range(5)]
results = [future.result() for future in futures]
print(f"Results: {results}")
์์(ํ๋ก์ธ์ค ๊ธฐ๋ฐ):
from concurrent.futures import ProcessPoolExecutor
import time
def task(n):
print(f"Task {n}: Starting")
time.sleep(1) # Simulate some work
print(f"Task {n}: Finished")
return n * 2
if __name__ == '__main__':
with ProcessPoolExecutor(max_workers=3) as executor:
futures = [executor.submit(task, i) for i in range(5)]
results = [future.result() for future in futures]
print(f"Results: {results}")
์ฅ์ :
- ์ค๋ ๋ ๋๋ ํ๋ก์ธ์ค๋ฅผ ๊ด๋ฆฌํ๊ธฐ ์ํ ๊ฐ์ํ๋ ์ธํฐํ์ด์ค.
- ์ค๋ ๋ ๊ธฐ๋ฐ ๋ฐ ํ๋ก์ธ์ค ๊ธฐ๋ฐ ๋์์ฑ ๊ฐ์ ์ฌ์ด ์ ํ์ ํ์ฉํฉ๋๋ค.
- ์คํ๊ธฐ ์ ํ์ ๋ฐ๋ผ CPU ๋ฐ์ด๋ ๋ฐ I/O ๋ฐ์ด๋ ์์ ๋ชจ๋์ ์ ํฉํฉ๋๋ค.
๋จ์ :
- ์ค๋ ๋ ๊ธฐ๋ฐ ์คํ์ ์ฌ์ ํ GIL ์ ํ์ ์ํฅ์ ๋ฐ์ต๋๋ค.
- ํ๋ก์ธ์ค ๊ธฐ๋ฐ ์คํ์ ๋ฉ๋ชจ๋ฆฌ ์ค๋ฒํค๋๊ฐ ๋ ํฝ๋๋ค.
4. C ํ์ฅ ๋ฐ ๋ค์ดํฐ๋ธ ์ฝ๋
GIL์ ์ฐํํ๋ ๊ฐ์ฅ ํจ๊ณผ์ ์ธ ๋ฐฉ๋ฒ ์ค ํ๋๋ CPU ์ง์ฝ์ ์์ ์ C ํ์ฅ ๋๋ ๊ธฐํ ๋ค์ดํฐ๋ธ ์ฝ๋๋ก ์คํ๋ก๋ํ๋ ๊ฒ์ ๋๋ค. ์ธํฐํ๋ฆฌํฐ๊ฐ C ์ฝ๋๋ฅผ ์คํํ ๋ GIL์ด ํด์ ๋์ด ๋ค๋ฅธ ์ค๋ ๋๊ฐ ๋์์ ์คํ๋ ์ ์์ต๋๋ค. ์ด๊ฒ์ NumPy์ ๊ฐ์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์์ ์ผ๋ฐ์ ์ผ๋ก ์ฌ์ฉ๋๋ฉฐ, GIL์ ํด์ ํ๋ฉด์ C์์ ์์น ๊ณ์ฐ์ ์ํํฉ๋๋ค.
์: ๊ณผํ ์ปดํจํ ์ ๋๋ฆฌ ์ฌ์ฉ๋๋ Python ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ธ NumPy๋ C์์ ๋ง์ ๊ธฐ๋ฅ์ ๊ตฌํํ์ฌ GIL์ ์ํด ์ ํ๋์ง ์๊ณ ๋ณ๋ ฌ ๊ณ์ฐ์ ์ํํ ์ ์๋๋ก ํฉ๋๋ค. ์ด๊ฒ์ด NumPy๊ฐ ์ฑ๋ฅ์ด ์ค์ํ ํ๋ ฌ ๊ณฑ์ ๋ฐ ์ ํธ ์ฒ๋ฆฌ์ ๊ฐ์ ์์ ์ ์์ฃผ ์ฌ์ฉ๋๋ ์ด์ ์ ๋๋ค.
์ฅ์ :
- CPU ๋ฐ์ด๋ ์์ ์ ๋ํ ์ง์ ํ ๋ณ๋ ฌ ์ฒ๋ฆฌ.
- ์์ Python ์ฝ๋์ ๋นํด ์ฑ๋ฅ์ ํฌ๊ฒ ํฅ์์ํฌ ์ ์์ต๋๋ค.
๋จ์ :
- C ์ฝ๋๋ฅผ ์์ฑํ๊ณ ์ ์ง ๊ด๋ฆฌํด์ผ ํ๋ฏ๋ก Python๋ณด๋ค ๋ ๋ณต์กํ ์ ์์ต๋๋ค.
- ํ๋ก์ ํธ์ ๋ณต์ก์ฑ์ ์ฆ๊ฐ์ํค๊ณ ์ธ๋ถ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ๋ํ ์ข ์์ฑ์ ๋์ ํฉ๋๋ค.
- ์ต์ ์ ์ฑ๋ฅ์ ์ํด ํ๋ซํผ๋ณ ์ฝ๋๊ฐ ํ์ํ ์ ์์ต๋๋ค.
5. ๋์ฒด Python ๊ตฌํ
GIL์ด ์๋ ์ฌ๋ฌ ๋์ฒด Python ๊ตฌํ์ด ์์ต๋๋ค. Jython(Java Virtual Machine์์ ์คํ) ๋ฐ IronPython(.NET ํ๋ ์์ํฌ์์ ์คํ)๊ณผ ๊ฐ์ ์ด๋ฌํ ๊ตฌํ์ ๋ค๋ฅธ ๋์์ฑ ๋ชจ๋ธ์ ์ ๊ณตํ๋ฉฐ GIL์ ์ ํ ์์ด ์ง์ ํ ๋ณ๋ ฌ ์ฒ๋ฆฌ๋ฅผ ๋ฌ์ฑํ๋ ๋ฐ ์ฌ์ฉํ ์ ์์ต๋๋ค.
๊ทธ๋ฌ๋ ์ด๋ฌํ ๊ตฌํ์ ํน์ Python ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ํธํ์ฑ ๋ฌธ์ ๊ฐ ์๋ ๊ฒฝ์ฐ๊ฐ ๋ง์ผ๋ฉฐ ๋ชจ๋ ํ๋ก์ ํธ์ ์ ํฉํ์ง ์์ ์ ์์ต๋๋ค.
์ฅ์ :
- GIL ์ ํ ์์ด ์ง์ ํ ๋ณ๋ ฌ ์ฒ๋ฆฌ.
- Java ๋๋ .NET ์ํ๊ณ์์ ํตํฉ.
๋จ์ :
- Python ๋ผ์ด๋ธ๋ฌ๋ฆฌ์์ ์ ์ฌ์ ์ธ ํธํ์ฑ ๋ฌธ์ .
- CPython์ ๋นํด ๋ค๋ฅธ ์ฑ๋ฅ ํน์ฑ.
- CPython์ ๋นํด ๋ ์์ ์ปค๋ฎค๋ํฐ์ ๋ ์ ์ ์ง์.
์ค์ ์์ ๋ฐ ์ฌ๋ก ์ฐ๊ตฌ
GIL์ ์ํฅ๊ณผ ๋ค์ํ ์ํ ์ ๋ต์ ํจ๊ณผ๋ฅผ ์ค๋ช ํ๊ธฐ ์ํด ๋ช ๊ฐ์ง ์ค์ ์ฌ๋ก๋ฅผ ์ดํด๋ณด๊ฒ ์ต๋๋ค.
์ฌ๋ก ์ฐ๊ตฌ 1: ์ด๋ฏธ์ง ์ฒ๋ฆฌ ์ ํ๋ฆฌ์ผ์ด์
์ด๋ฏธ์ง ์ฒ๋ฆฌ ์ ํ๋ฆฌ์ผ์ด์ ์ ํํฐ๋ง, ํฌ๊ธฐ ์กฐ์ ๋ฐ ์์ ๋ณด์ ๊ณผ ๊ฐ์ ๋ค์ํ ์ด๋ฏธ์ง ์์ ์ ์ํํฉ๋๋ค. ์ด๋ฌํ ์์ ์ CPU ๋ฐ์ด๋์ด๋ฉฐ ๊ณ์ฐ ์ง์ฝ์ ์ผ ์ ์์ต๋๋ค. CPython์ ์ฌ์ฉํ ๋ฉํฐ ์ค๋ ๋ฉ์ ์ฌ์ฉํ๋ ์์งํ ๊ตฌํ์์๋ GIL์ด ์ง์ ํ ๋ณ๋ ฌ ์ฒ๋ฆฌ๋ฅผ ๋ฐฉ์งํ์ฌ ๋ฉํฐ ์ฝ์ด ์์คํ ์์ ์ฑ๋ฅ์ด ์ ํ๋ฉ๋๋ค.
ํด๊ฒฐ์ฑ : ๋ฉํฐํ๋ก์ธ์ฑ์ ์ฌ์ฉํ์ฌ ์ด๋ฏธ์ง ์ฒ๋ฆฌ ์์ ์ ์ฌ๋ฌ ํ๋ก์ธ์ค์ ๋ถ์ฐํ๋ฉด ์ฑ๋ฅ์ ํฌ๊ฒ ํฅ์์ํฌ ์ ์์ต๋๋ค. ๊ฐ ํ๋ก์ธ์ค๋ ์๋ก ๋ค๋ฅธ ์ด๋ฏธ์ง ๋๋ ๋์ผํ ์ด๋ฏธ์ง์ ๋ค๋ฅธ ๋ถ๋ถ์์ ๋์์ ์๋ํ์ฌ GIL ์ ํ์ ์ฐํํ ์ ์์ต๋๋ค.
์ฌ๋ก ์ฐ๊ตฌ 2: API ์์ฒญ์ ์ฒ๋ฆฌํ๋ ์น ์๋ฒ
์น ์๋ฒ๋ ๋ฐ์ดํฐ๋ฒ ์ด์ค์์ ๋ฐ์ดํฐ๋ฅผ ์ฝ๊ณ ์ธ๋ถ API ํธ์ถ์ ํฌํจํ๋ ์๋ง์ API ์์ฒญ์ ์ฒ๋ฆฌํฉ๋๋ค. ์ด๋ฌํ ์์ ์ I/O ๋ฐ์ด๋์ ๋๋ค. ์ด ๊ฒฝ์ฐ `asyncio`๋ฅผ ์ฌ์ฉํ ๋น๋๊ธฐ ํ๋ก๊ทธ๋๋ฐ์ด ๋ฉํฐ ์ค๋ ๋ฉ๋ณด๋ค ๋ ํจ์จ์ ์ผ ์ ์์ต๋๋ค. ์๋ฒ๋ I/O ์์ ์ด ์๋ฃ๋ ๋๊น์ง ๊ธฐ๋ค๋ฆฌ๋ ๋์ ์ฌ๋ฌ ์์ฒญ์ ์ ํํ์ฌ ์ฌ๋ฌ ์์ฒญ์ ๋์์ ์ฒ๋ฆฌํ ์ ์์ต๋๋ค.
์ฌ๋ก ์ฐ๊ตฌ 3: ๊ณผํ ์ปดํจํ ์ ํ๋ฆฌ์ผ์ด์
๊ณผํ ์ปดํจํ ์ ํ๋ฆฌ์ผ์ด์ ์ ๋๊ท๋ชจ ๋ฐ์ดํฐ ์ธํธ์ ๋ํด ๋ณต์กํ ์์น ๊ณ์ฐ์ ์ํํฉ๋๋ค. ์ด๋ฌํ ๊ณ์ฐ์ CPU ๋ฐ์ด๋์ด๋ฉฐ ๋์ ์ฑ๋ฅ์ด ํ์ํฉ๋๋ค. C์์ ๋ง์ ๊ธฐ๋ฅ์ ๊ตฌํํ๋ NumPy๋ฅผ ์ฌ์ฉํ๋ฉด ๊ณ์ฐ ์ค์ GIL์ ํด์ ํ์ฌ ์ฑ๋ฅ์ ํฌ๊ฒ ํฅ์์ํฌ ์ ์์ต๋๋ค. ๋๋ ๋ฉํฐํ๋ก์ธ์ฑ์ ์ฌ์ฉํ์ฌ ๊ณ์ฐ์ ์ฌ๋ฌ ํ๋ก์ธ์ค์ ๋ถ์ฐ์ํฌ ์ ์์ต๋๋ค.
GIL ์ฒ๋ฆฌ ๋ชจ๋ฒ ์ฌ๋ก
GIL์ ์ฒ๋ฆฌํ๊ธฐ ์ํ ๋ช ๊ฐ์ง ๋ชจ๋ฒ ์ฌ๋ก๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
- CPU ๋ฐ์ด๋ ๋ฐ I/O ๋ฐ์ด๋ ์์ ์๋ณ: ์ ํ๋ฆฌ์ผ์ด์ ์ด ์ฃผ๋ก CPU ๋ฐ์ด๋์ธ์ง I/O ๋ฐ์ด๋์ธ์ง ํ์ธํ์ฌ ์ ์ ํ ๋์์ฑ ์ ๋ต์ ์ ํํฉ๋๋ค.
- CPU ๋ฐ์ด๋ ์์ ์ ๋ฉํฐํ๋ก์ธ์ฑ ์ฌ์ฉ: CPU ๋ฐ์ด๋ ์์ ์ ์ฒ๋ฆฌํ ๋ `multiprocessing` ๋ชจ๋์ ์ฌ์ฉํ์ฌ GIL์ ์ฐํํ๊ณ ์ง์ ํ ๋ณ๋ ฌ ์ฒ๋ฆฌ๋ฅผ ๋ฌ์ฑํฉ๋๋ค.
- I/O ๋ฐ์ด๋ ์์ ์ ๋น๋๊ธฐ ํ๋ก๊ทธ๋๋ฐ ์ฌ์ฉ: I/O ๋ฐ์ด๋ ์์ ์ ๊ฒฝ์ฐ `asyncio` ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ํ์ฉํ์ฌ ์ฌ๋ฌ ๋์ ์์ ์ ํจ์จ์ ์ผ๋ก ์ฒ๋ฆฌํฉ๋๋ค.
- CPU ์ง์ฝ์ ์์ ์ C ํ์ฅ์ผ๋ก ์คํ๋ก๋: ์ฑ๋ฅ์ด ์ค์ํ ๊ฒฝ์ฐ CPU ์ง์ฝ์ ์์ ์ C๋ก ๊ตฌํํ๊ณ ๊ณ์ฐ ์ค์ GIL์ ํด์ ํ๋ ๊ฒ์ ๊ณ ๋ คํฉ๋๋ค.
- ๋์ฒด Python ๊ตฌํ ๊ณ ๋ ค: GIL์ด ์ฃผ์ ๋ณ๋ชฉ ํ์์ด๊ณ ํธํ์ฑ์ ๋ฌธ์ ๊ฐ ์๋ ๊ฒฝ์ฐ Jython ๋๋ IronPython๊ณผ ๊ฐ์ ๋์ฒด Python ๊ตฌํ์ ์ดํด๋ณด์ธ์.
- ์ฝ๋ ํ๋กํ์ผ๋ง: ํ๋กํ์ผ๋ง ๋๊ตฌ๋ฅผ ์ฌ์ฉํ์ฌ ์ฑ๋ฅ ๋ณ๋ชฉ ํ์์ ์๋ณํ๊ณ GIL์ด ์ค์ ๋ก ์ ํ ์์์ธ์ง ํ์ธํฉ๋๋ค.
- ๋จ์ผ ์ค๋ ๋ ์ฑ๋ฅ ์ต์ ํ: ๋์์ฑ์ ์ง์คํ๊ธฐ ์ ์ ์ฝ๋๊ฐ ๋จ์ผ ์ค๋ ๋ ์ฑ๋ฅ์ ์ต์ ํ๋์๋์ง ํ์ธํฉ๋๋ค.
GIL์ ๋ฏธ๋
GIL์ Python ์ปค๋ฎค๋ํฐ ๋ด์์ ์ค๋ซ๋์ ๋ ผ์๋์ด ์จ ์ฃผ์ ์ ๋๋ค. GIL์ ์ํฅ์ ์ ๊ฑฐํ๊ฑฐ๋ ํฌ๊ฒ ์ค์ด๊ธฐ ์ํ ์๋๊ฐ ์ฌ๋ฌ ๋ฒ ์์์ง๋ง Python ์ธํฐํ๋ฆฌํฐ์ ๋ณต์ก์ฑ๊ณผ ๊ธฐ์กด ์ฝ๋์์ ํธํ์ฑ์ ์ ์งํด์ผ ํ ํ์์ฑ์ผ๋ก ์ธํด ์ด๋ฌํ ๋ ธ๋ ฅ์ ์ด๋ ค์์ด ์์์ต๋๋ค.
๊ทธ๋ฌ๋ Python ์ปค๋ฎค๋ํฐ๋ ๋ค์๊ณผ ๊ฐ์ ์ ์ฌ์ ์ธ ์๋ฃจ์ ์ ๊ณ์ ํ๊ตฌํ๊ณ ์์ต๋๋ค.
- ์๋ธ ์ธํฐํ๋ฆฌํฐ: ๋จ์ผ ํ๋ก์ธ์ค ๋ด์์ ๋ณ๋ ฌ ์ฒ๋ฆฌ๋ฅผ ๋ฌ์ฑํ๊ธฐ ์ํด ์๋ธ ์ธํฐํ๋ฆฌํฐ๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ ํ๊ตฌํฉ๋๋ค.
- ์ธ๋ถํ๋ ์ ๊ธ: GIL์ ๋ฒ์๋ฅผ ์ค์ด๊ธฐ ์ํด ๋ ์ธ๋ถํ๋ ์ ๊ธ ๋ฉ์ปค๋์ฆ์ ๊ตฌํํฉ๋๋ค.
- ํฅ์๋ ๋ฉ๋ชจ๋ฆฌ ๊ด๋ฆฌ: GIL์ด ํ์ํ์ง ์์ ๋์ฒด ๋ฉ๋ชจ๋ฆฌ ๊ด๋ฆฌ ์ฒด๊ณ๋ฅผ ๊ฐ๋ฐํฉ๋๋ค.
GIL์ ๋ฏธ๋๋ ๋ถํ์คํ์ง๋ง, ์ง์์ ์ธ ์ฐ๊ตฌ ๊ฐ๋ฐ๋ก ์ธํด Python ๋ฐ ๊ธฐํ GIL์ ์ํฅ์ ๋ฐ๋ ์ธ์ด์์ ๋์์ฑ ๋ฐ ๋ณ๋ ฌ์ฑ์ด ํฅ์๋ ๊ฐ๋ฅ์ฑ์ด ๋์ต๋๋ค.
๊ฒฐ๋ก
๊ธ๋ก๋ฒ ์ธํฐํ๋ฆฌํฐ ๋ฝ(GIL)์ Python ๋ฐ ๊ธฐํ ์ธ์ด๋ก ๋์ ์ ํ๋ฆฌ์ผ์ด์ ์ ์ค๊ณํ ๋ ๊ณ ๋ คํด์ผ ํ ์ค์ํ ์์์ ๋๋ค. ์ด๋ ์ด๋ฌํ ์ธ์ด์ ๋ด๋ถ ์๋์ ๋จ์ํํ์ง๋ง CPU ๋ฐ์ด๋ ์์ ์ ๋ํ ์ง์ ํ ๋ณ๋ ฌ ์ฒ๋ฆฌ์ ์ ํ์ ๋ก๋๋ค. GIL์ ์ํฅ์ ์ดํดํ๊ณ ๋ฉํฐํ๋ก์ธ์ฑ, ๋น๋๊ธฐ ํ๋ก๊ทธ๋๋ฐ ๋ฐ C ํ์ฅ๊ณผ ๊ฐ์ ์ ์ ํ ์ํ ์ ๋ต์ ์ฌ์ฉํจ์ผ๋ก์จ ๊ฐ๋ฐ์๋ ์ด๋ฌํ ์ ํ์ ๊ทน๋ณตํ๊ณ ์ ํ๋ฆฌ์ผ์ด์ ์์ ํจ์จ์ ์ธ ๋์์ฑ์ ๋ฌ์ฑํ ์ ์์ต๋๋ค. Python ์ปค๋ฎค๋ํฐ๊ฐ ์ ์ฌ์ ์ธ ์๋ฃจ์ ์ ๊ณ์ ํ๊ตฌํจ์ ๋ฐ๋ผ GIL์ ๋ฏธ๋์ ๋์์ฑ์ ๋ฏธ์น๋ ์ํฅ์ ํ๋ฐํ ๊ฐ๋ฐ๊ณผ ํ์ ์ ์์ญ์ผ๋ก ๋จ์ ์์ต๋๋ค.
์ด ๋ถ์์ ๊ตญ์ ์ฒญ์ค์๊ฒ GIL, ๊ทธ ์ ํ ์ฌํญ ๋ฐ ์ด๋ฌํ ์ ํ ์ฌํญ์ ๊ทน๋ณตํ๊ธฐ ์ํ ์ ๋ต์ ๋ํ ํฌ๊ด์ ์ธ ์ดํด๋ฅผ ์ ๊ณตํ๋๋ก ์ค๊ณ๋์์ต๋๋ค. ๋ค์ํ ๊ด์ ๊ณผ ์์๋ฅผ ๊ณ ๋ คํจ์ผ๋ก์จ ๋ค์ํ ๋งฅ๋ฝ๊ณผ ๋ค์ํ ๋ฌธํ์ ๋ฐฐ๊ฒฝ์ ์ ์ฉํ ์ ์๋ ์คํ ๊ฐ๋ฅํ ํต์ฐฐ๋ ฅ์ ์ ๊ณตํ๋ ๊ฒ์ ๋ชฉํ๋ก ํฉ๋๋ค. ์ฝ๋๋ฅผ ํ๋กํ์ผ๋งํ๊ณ ํน์ ์๊ตฌ ์ฌํญ๊ณผ ์ ํ๋ฆฌ์ผ์ด์ ์๊ตฌ ์ฌํญ์ ๊ฐ์ฅ ์ ํฉํ ๋์์ฑ ์ ๋ต์ ์ ํํ๋ ๊ฒ์ ์์ง ๋ง์ธ์.