[ํ์ด์ฌ] Multiprocessing, Multithreading ์์ ๋ถํ ๋ฐ ํ ๋น
์๋ณธ ๊ฒ์๊ธ: https://velog.io/@euisuk-chung/ํ์ด์ฌ-Multiprocessing-Multithreading-์์-๋ถํ -๋ฐ-ํ ๋น
๋ฉํฐํ๋ก์ธ์ฑ
๊ณผ ๋ฉํฐ์ค๋ ๋ฉ
์์ ์์ ๋ถํ ๊ณผ ์์
ํ ๋น์ ๊ฐ๊ฐ ๋ค๋ฅด๊ฒ ์ด๋ฃจ์ด์ง๋๋ค. ์ด ๊ณผ์ ์ ์ดํดํ๊ธฐ ์ํด์๋ ๋จผ์ , ์ปดํจํฐ์ ์์(ํนํ CPU์ ๋ฉ๋ชจ๋ฆฌ) ์ฌ์ฉ ๋ฐฉ์๊ณผ ์์
์ ์ข
๋ฅ(์: CPU ์ง์ฝ์ vs. I/O ์ง์ฝ์ )๋ฅผ ๊ณ ๋ คํด์ผ ํฉ๋๋ค.
๋ฉํฐํ๋ก์ธ์ฑ(Multiprocessing)์ ์์ ๋ถํ
๋ฉํฐํ๋ก์ธ์ฑ์์๋ ๊ฐ ํ๋ก์ธ์ค๊ฐ ๋ ๋ฆฝ๋ ๋ฉ๋ชจ๋ฆฌ ๊ณต๊ฐ์ ๊ฐ์ง๋๋ค. ์ด๋ ๊ฐ ํ๋ก์ธ์ค๊ฐ ์์คํ ์ ์์์ ๋ ๋ฆฝ์ ์ผ๋ก ํ ๋น๋ฐ๋๋ค๋ ์๋ฏธ์ ๋๋ค. CPU ์์์ ๋ถํ ์ ์ด์ ์ฒด์ ์ ์ค์ผ์ค๋ฌ์ ์ํด ๊ด๋ฆฌ๋๋ฉฐ, ์ฌ๋ฌ ํ๋ก์ธ์ค ๊ฐ์ CPU ์๊ฐ์ ๊ณต์ ํ๊ฒ ๋ถ๋ฐฐํฉ๋๋ค.
์์ ์ด N๊ฐ์ ํ๋ก์ธ์ค์ ๋ถ๋ฐฐ๋ ๋, ์ด๋ก ์ ์ผ๋ก๋ ๊ฐ ํ๋ก์ธ์ค์ ์์ ์ 1/N์ ํ ๋นํ ์ ์์ต๋๋ค. ํ์ง๋ง ์ค์ ๋ถํ ์ ์์ ์ ์ฑ๊ฒฉ, ํ๋ก์ธ์ค์ ์คํ ์ํ, ์์คํ ์ ๋ค๋ฅธ ์๊ตฌ ์ฌํญ ๋ฑ์ ๋ฐ๋ผ ๋ฌ๋ผ์ง ์ ์์ต๋๋ค. ์๋ฅผ ๋ค์ด, ์ด๋ค ํ๋ก์ธ์ค๋ CPU๋ฅผ ๋ง์ด ์ฌ์ฉํ๋ ๋ฐ๋ฉด, ๋ค๋ฅธ ํ๋ก์ธ์ค๋ ๋๊ธฐ ์ํ์ ์์ ์ ์์ต๋๋ค.
๋ฉํฐ์ค๋ ๋ฉ(Multithreading)์ ์์ ๋ถํ
๋ฉํฐ์ค๋ ๋ฉ์์๋ ๋ชจ๋ ์ค๋ ๋๊ฐ ํ๋ก์ธ์ค์ ๋ฉ๋ชจ๋ฆฌ ๊ณต๊ฐ์ ๊ณต์ ํฉ๋๋ค. ๋ฐ๋ผ์, ๋ฉ๋ชจ๋ฆฌ ์์์ ๋ณ๋๋ก ๋ถํ ๋์ง ์๊ณ , ๋ชจ๋ ์ค๋ ๋๊ฐ ๊ฐ์ ๋ฉ๋ชจ๋ฆฌ ์์ญ์ ์ ๊ทผํ ์ ์์ต๋๋ค. CPU ์์์ ๊ฒฝ์ฐ, ์ด์ ์ฒด์ ์ ์ค๋ ๋ ์ค์ผ์ค๋ฌ๊ฐ ๊ฐ ์ค๋ ๋์ CPU ์๊ฐ์ ํ ๋นํฉ๋๋ค.
์ค๋ ๋ ๊ฐ์ ์์ ๋ถํ ์ ํ๋ก์ธ์ค ๋ด์์ ์ด๋ฃจ์ด์ง๋ฉฐ, ์ค๋ ๋๊ฐ ์ํํ๋ ์์ ์ ์ผ๋ฐ์ ์ผ๋ก ๋ ์๊ณ , ๊ตฌ์ฒด์ ์ธ ์์ ๋จ์๋ก ๋๋์ด์ง๋๋ค. ๋ฉํฐ์ค๋ ๋ฉ ํ๊ฒฝ์์๋ I/O ์์ ์ด ์งํ๋๋ ๋์ ๋ค๋ฅธ ์ค๋ ๋๊ฐ CPU๋ฅผ ์ฌ์ฉํ ์ ์์ด, ์ ์ฒด์ ์ธ ํ๋ก๊ทธ๋จ์ ํจ์จ์ฑ์ ๋์ผ ์ ์์ต๋๋ค.
โญ (Q&A) ์ฌ๊ธฐ์ ์ ๊น!!
Q. ๋ฉํฐํ๋ก์ธ์ค์์
ํ๋ก์ธ์คA
์ํ๋ก์ธ์คB
๊ฐ ์๋ค๊ณ ๊ฐ์ ํด๋ณด๊ฒ ์ต๋๋ค. ๊ทธ๋ผ 4์ด๋ผ๋ ๊ฐ์ฉ ์์์ด ์์๋ ๋ง์ฝ ํ๋ก์ธ์คA๊ฐ ๋จผ์ ๋๋๋ฉด ๋๋จธ์ง ํ๋ก์ธ์ค์ธ ํ๋ก์ธ์คB๊ฐ ๋จ์ ์์ 4๊ฐ๋ฅผ ๋ค ์ฐ๋๋ก ๋ฐ๋๋๋ก ์๋์ผ๋ก ํ ๋นํด์ฃผ๋์?A. ์ค์ ๋ก ํ๋ก์ธ์คA๊ฐ ์ข ๋ฃ๋์ด ์์์ด ๋ฐํ๋ ๋, ํ๋ก์ธ์คB๊ฐ ์๋์ผ๋ก ๋ชจ๋ ์์์ ํ์ฉํ๋๋ก ์์คํ ์ด ์ฌ์กฐ์ ๋๋ ๊ฒ์ ๋ณด์ฅ๋์ง ์์ต๋๋ค. ์์์ ์ฌํ ๋น์ ์ด์ ์ฒด์ ์ ์ค์ผ์ค๋ง ์๊ณ ๋ฆฌ์ฆ๊ณผ ์ ์ฑ ์ ๋ฐ๋ผ ๊ฒฐ์ ๋๋ฉฐ, ๋ค๋ฅธ ๋๊ธฐ ์ค์ธ ํ๋ก์ธ์ค๋ ์์คํ ์ ์ ๋ฐ์ ์ธ ์์ ๊ด๋ฆฌ ์ ๋ต์ ์ํด ์ํฅ์ ๋ฐ์ต๋๋ค. ํ๋ก์ธ์คB๊ฐ ์ถ๊ฐ ์์์ ํ์ฉํ๋ ค๋ฉด, ํด๋น ํ๋ก์ธ์ค๊ฐ ๋ณ๋ ฌ ์ฒ๋ฆฌ๋ฅผ ์ง์ํ๊ณ ์ถ๊ฐ CPU ์ฝ์ด๋ฅผ ํจ์จ์ ์ผ๋ก ํ์ฉํ ์ ์๋ ๊ตฌ์กฐ๋ก ์ค๊ณ๋์ด์ผ ํฉ๋๋ค.
โญ ์ถ๊ฐ ์ค๋ช : ์์ ํ ๋น์ ๋์ ๋ฐฉ์
โ CPU ์ฝ์ด ํ ๋น: ๊ฐ์ฉ ์์์ด CPU ์ฝ์ด๋ผ๊ณ ํ ๋, ๊ฐ ํ๋ก์ธ์ค๋ ์ด์ ์ฒด์ ์ ์ํด ํ๋ ์ด์์ CPU ์ฝ์ด์ ํ ๋น๋ ์ ์์ต๋๋ค. ํ๋ก์ธ์คA์ ํ๋ก์ธ์คB๊ฐ ๊ฐ๊ฐ 2๊ฐ์ CPU ์ฝ์ด๋ฅผ ์ฌ์ฉํ๊ณ ์๋ค๋ฉด, ์ด๋ ํ๋ก์ธ์ค๊ฐ ์คํ๋๋ ๋์ ๋์์ 2๊ฐ์ ์์ ์ ์ํํ ์ ์์์ ์๋ฏธํฉ๋๋ค.
โ ๋์ ์ฌํ ๋น: ํ๋ก์ธ์คA๊ฐ ์์ ์ ์๋ฃํ๊ณ ์ข ๋ฃ๋๋ฉด, ๊ทธ ํ๋ก์ธ์ค์ ํ ๋น๋์๋ ์์(์ฌ๊ธฐ์๋ CPU ์ฝ์ด)์ ์์คํ ์ ๋ฐํ๋ฉ๋๋ค. ์ดํ ์ด์ ์ฒด์ ์ ์ค์ผ์ค๋ฌ๋ ์ด์ ์ฌ์ฉ ๊ฐ๋ฅํ ์์์ ๋ค์ ๋ถ๋ฐฐํ ์ ์๊ฒ ๋ฉ๋๋ค. ํ์ง๋ง, ์๋์ผ๋ก ํ๋ก์ธ์คB๊ฐ ๋๋จธ์ง ์์์ ๋ชจ๋ ์ฌ์ฉํ๋๋ก ํ ๋น๋ฐ๋ ๊ฒ์ ์๋์ผ๋ก ์ด๋ฃจ์ด์ง์ง ์์ต๋๋ค. โ ์์์ ์ฌํ ๋น ์กฐ๊ฑด: ํ๋ก์ธ์คB๊ฐ ์ถ๊ฐ์ ์ธ CPU ์ฝ์ด๋ฅผ ์ฌ์ฉํ ์ ์๊ฒ ๋๋์ง ์ฌ๋ถ๋ ์ฌ๋ฌ ์์์ ์ํด ๊ฒฐ์ ๋ฉ๋๋ค. ์ด๋ ์ด์ ์ฒด์ ์ ์ค์ผ์ค๋ง ์ ์ฑ , ํ๋ก์ธ์ค์ ์ฐ์ ์์, ๊ทธ๋ฆฌ๊ณ ํ๋ก์ธ์คB๊ฐ ์ถ๊ฐ ์์์ ํจ๊ณผ์ ์ผ๋ก ํ์ฉํ ์ ์๋์ง(์: ๋ณ๋ ฌ ์ฒ๋ฆฌ๊ฐ ๊ฐ๋ฅํ ์์ ์ธ์ง)์ ๋ฐ๋ผ ๋ฌ๋ผ์ง ์ ์์ต๋๋ค. โ ์์ ์ฌ์ฉ์ ์ต์ ํ: ๋๋ถ๋ถ์ ํ๋ ์ด์ ์ฒด์ ๋ ์์คํ ์์์ ํจ์จ์ ์ผ๋ก ํ์ฉํ๊ธฐ ์ํ ๋ณต์กํ ์ค์ผ์ค๋ง ์๊ณ ๋ฆฌ์ฆ์ ์ฌ์ฉํฉ๋๋ค. ํ๋ก์ธ์คA๊ฐ ์ข ๋ฃ๋์ด ์์์ด ๋ฐํ๋๋ฉด, ์ด ์์์ ์์คํ ์ ๋ค๋ฅธ ๋๊ธฐ ์ค์ธ ํ๋ก์ธ์ค์ ํ ๋น๋ ์ ์์ต๋๋ค. ๊ทธ๋ฌ๋, ํน์ ํ๋ก์ธ์ค๊ฐ ์๋์ผ๋ก ๋ชจ๋ ๊ฐ์ฉ ์์์ ๋ ์ ํ๋๋ก ์์คํ ์ด ์ฌ์กฐ์ ํ๋ ๊ฒ์ ์ผ๋ฐ์ ์ธ ๊ฒฝ์ฐ๊ฐ ์๋๋๋ค.
์์ ํ ๋น ๋ฐฉ์
์ค์ ์์ ํ ๋น์ ์ ํ๋ฆฌ์ผ์ด์ ๋ ๋ฒจ์์ ๊ฐ๋ฐ์๊ฐ ๊ฒฐ์ ํฉ๋๋ค. ๋ฉํฐํ๋ก์ธ์ฑ์ด๋ ๋ฉํฐ์ค๋ ๋ฉ์ ์ฌ์ฉํ ๋, ๊ฐ๊ฐ์ ํ๋ก์ธ์ค๋ ์ค๋ ๋์ ํ ๋นํ ์์ ์ ํฌ๊ธฐ์ ๋ฒ์๋ ํ๋ก๊ทธ๋จ์ ๊ตฌ์กฐ์ ์๊ตฌ ์ฌํญ์ ๋ฐ๋ผ ๋ฌ๋ผ์ง๋๋ค. ์๋ฅผ ๋ค์ด, ๋ฐ์ดํฐ ์ฒ๋ฆฌ ์์ ์ ์ฌ๋ฌ ํ๋ก์ธ์ค์ ๋ถ๋ฐฐํ ๋๋ ๊ฐ ํ๋ก์ธ์ค๊ฐ ์ฒ๋ฆฌํ ๋ฐ์ดํฐ์ ์์ ๊ท ๋ฑํ๊ฒ ๋๋๊ฑฐ๋, ํน์ ์กฐ๊ฑด์ ๋ง๋ ๋ฐ์ดํฐ๋ฅผ ํ ๋นํ๋ ๋ฐฉ์์ผ๋ก ๋ถํ ํ ์ ์์ต๋๋ค.
๋ฉํฐํ๋ก์ธ์ฑ๊ณผ ๋ฉํฐ์ค๋ ๋ฉ ๋ชจ๋ ์์
์ ๋ณ๋ ฌ ์ฒ๋ฆฌ๋ฅผ ํตํด ์ฑ๋ฅ์ ํฅ์์ํค์ง๋ง, ๊ทธ ๊ตฌํ ๋ฐฉ์๊ณผ ์ฌ์ฉ ์ฌ๋ก๋ ํฌ๊ฒ ๋ค๋ฆ
๋๋ค. ๋ฉํฐํ๋ก์ธ์ฑ
์ ๋
๋ฆฝ์ ์ธ ์์
์ด ๋ง๊ณ , ๊ฐ ์์
์ด ์๋นํ ์์ CPU ์์์ ํ์๋ก ํ ๋ ์ ๋ฆฌํ๋ฉฐ, ๋ฉํฐ์ค๋ ๋ฉ
์ ์์
๊ฐ์ ์์์ ๊ณต์ ํด์ผ ํ๊ฑฐ๋ I/O ๋ฐ์ด๋ ์์
์ด ๋ง์ ๋ ํจ๊ณผ์ ์
๋๋ค.
์์ ํ ๋น๊ณผ ์์ ๋ถ๋ฐฐ ๋ฐฉ์์ ๋ํด ๋ ์์ธํ ์ค๋ช ํ๊ฒ ์ต๋๋ค. ๊ธฐ๋ณธ์ ์ผ๋ก, ๋ฉํฐํ๋ก์ธ์ฑ๊ณผ ๋ฉํฐ์ค๋ ๋ฉ ํ๊ฒฝ์์์ ์์ ํ ๋น์ ์๋๊ณผ ์๋(๊ฐ๋ฐ์ ์ง์ ) ๋ฐฉ์์ ๋ชจ๋ ํฌํจํ ์ ์์ต๋๋ค.
์๋ ํ ๋น(์์คํ )
- ๊ฐ์ฉ ์์์ ์๋ ๋ถ๋ฐฐ: ์ด์ ์ฒด์ ์ ์ค์ผ์ค๋ฌ๊ฐ ํ๋ก์ธ์ค๋ ์ค๋ ๋์ ๋ํด CPU ์๊ฐ์ ์๋์ผ๋ก ํ ๋นํฉ๋๋ค. ์ด ๊ฒฝ์ฐ, ์ค์ผ์ค๋ฌ๋ ์์คํ ์ ํ์ฌ ๋ถํ, ํ๋ก์ธ์ค์ ์ฐ์ ์์, ํ๋ก์ธ์ค์ ์ํ(์คํ ์ค, ๋๊ธฐ ์ค ๋ฑ)์ ๊ฐ์ ์ฌ๋ฌ ์์ธ์ ๊ณ ๋ คํ์ฌ ์์์ ๋ถ๋ฐฐํฉ๋๋ค. ๋ํดํธ๋ก, ์์คํ ์ ๊ฐ๋ฅํ ๊ณต์ ํ๊ฒ ์์์ ๋ถ๋ฐฐํ๋ ค๊ณ ์๋ํ์ง๋ง, ์ด๋ โ1/Nโ์ด๋ผ๋ ๊ณ ์ ๋น์จ๋ก ์ ํํ ๋ถ๋ฐฐ๋๋ค๋ ์๋ฏธ๋ ์๋๋๋ค.
์๋ ํ ๋น(๊ฐ๋ฐ์ ์ง์ )
- ๊ฐ๋ฐ์์ ์ํ ๋ช ์์ ๋ถ๋ฐฐ: ๊ฐ๋ฐ์๋ ํ๋ก๊ทธ๋จ์ ์๊ตฌ ์ฌํญ๊ณผ ์์ ์ ํน์ฑ์ ๊ณ ๋ คํ์ฌ, ๊ฐ ํ๋ก์ธ์ค๋ ์ค๋ ๋์ ํ ๋น๋ ์์ ์ ์์ด๋ ์์์ ์ฌ์ฉ์ ๋ช ์์ ์ผ๋ก ์ง์ ํ ์ ์์ต๋๋ค. ์๋ฅผ ๋ค์ด, ๋ฐ์ดํฐ ์ฒ๋ฆฌ ์์ ์ ์ฌ๋ฌ ํ๋ก์ธ์ค์ ๋ถ๋ฐฐํ ๋ ํน์ ๊ธฐ์ค์ ๋ฐ๋ผ ์์ ์ ๋๋ ์ ์์ผ๋ฉฐ, ์ด๋ ์์ ์ ํจ์จ์ฑ๊ณผ ์คํ ์๊ฐ์ ์ํฅ์ ๋ฏธ์น ์ ์์ต๋๋ค.
๋ฉํฐํ๋ก์ธ์ฑ ์์ ํ ๋น ์์
์ด ์์์์๋ ๋๋์ ๋ฐ์ดํฐ๋ฅผ 4๊ฐ์ ์ฒญํฌ๋ก ๋๋๊ณ , ๊ฐ ์ฒญํฌ๋ฅผ ๋ณ๋์ ํ๋ก์ธ์ค์ ํ ๋นํ์ฌ ๋ณ๋ ฌ๋ก ์ฒ๋ฆฌํฉ๋๋ค. ์ด๋ ๊ฐ๋ฐ์๊ฐ ์์ ์ ๋ถ๋ฐฐ๋ฅผ ๋ช ์์ ์ผ๋ก ์ง์ ํ ๊ฒฝ์ฐ์ ๋๋ค.
1
2
3
4
5
6
7
8
9
10
11
12
13
from multiprocessing import Pool
def my_task(data_chunk):
# ๋ณต์กํ ๊ณ์ฐ ์ํ
result = sum(data_chunk)
return result
if __name__ == "__main__":
data = range(1000000) # ๋๋์ ๋ฐ์ดํฐ
chunks = [data[i::4] for i in range(4)] # ๋ฐ์ดํฐ๋ฅผ 4๊ฐ์ ์ฒญํฌ๋ก ๋๋
with Pool(4) as p: # 4๊ฐ์ ํ๋ก์ธ์ค ํ ์์ฑ
results = p.map(my_task, chunks) # ๊ฐ ์ฒญํฌ๋ฅผ ๋ณ๋์ ํ๋ก์ธ์ค์ ํ ๋น
์ ํ์ด์ฌ ์ฝ๋์์ multiprocessing.Pool
์ ์ฌ์ฉํ์ฌ ๋ฉํฐํ๋ก์ธ์ฑ์ ๊ตฌํํ ๋, ์์ ํ ๋น์ ๋ค์๊ณผ ๊ฐ์ด ์ด๋ฃจ์ด์ง๋๋ค:
ํ๋ก์ธ์ค ํ๊ณผ CPU ์ฝ์ด ํ ๋น
ํ๋ก์ธ์ค ํ ์์ฑ
: Pool(4)์ ์ํด 4๊ฐ์ ๋ณ๋ ํ๋ก์ธ์ค๊ฐ ์์ฑ๋ฉ๋๋ค. ์ด๋ ๋ฉํฐํ๋ก์ธ์ฑ์ ์ํ ํ๋ก์ธ์ค ํ๋ก, ๋ณ๋ ฌ ์์ ์ ์ํํ๊ธฐ ์ํด ์ค๋น๋ ํ๋ก์ธ์ค ์งํฉ์ ๋๋ค.CPU ์ฝ์ด ์ฌ์ฉ
: ์์คํ ์ 8๊ฐ์ CPU ์ฝ์ด๊ฐ ์๋ ๊ฒฝ์ฐ, Pool(4)์ ์ํด ์์ฑ๋ ๊ฐ ํ๋ก์ธ์ค๋ ์ด์ฉ ๊ฐ๋ฅํ CPU ์ฝ์ด ์ค ํ๋๋ฅผ ์ฌ์ฉํ ์ ์๊ฒ ๋ฉ๋๋ค. ์ฌ๊ธฐ์ ์ค์ํ ์ ์, ํ๋ก์ธ์ค ํ์ ์ํด ์์ฑ๋ ํ๋ก์ธ์ค ์๊ฐ ์์คํ ์ CPU ์ฝ์ด ์๋ณด๋ค ์ ๊ธฐ ๋๋ฌธ์, ๋ชจ๋ ํ๋ก์ธ์ค๊ฐ ๋์์ ์คํ๋ ์ ์์ผ๋ฉฐ, ๊ฐ๊ฐ ๋ณ๋์ CPU ์ฝ์ด์ ํ ๋น๋ ๊ฐ๋ฅ์ฑ์ด ๋์ต๋๋ค.
์์ ์ฒ๋ฆฌ ๋ฐฉ์
๋ณ๋ ฌ ์ฒ๋ฆฌ
: ์์ฑ๋ 4๊ฐ์ ํ๋ก์ธ์ค๋ ๋์์ ์คํ๋์ด ๊ฐ๊ฐ ํ ๋น๋ ์์ (๋ฐ์ดํฐ ์ฒญํฌ)์ ์ฒ๋ฆฌํฉ๋๋ค. ์์คํ ์ ์ฌ์ ์ฝ์ด๊ฐ ์ถฉ๋ถํ ์๊ธฐ ๋๋ฌธ์, ์ด ํ๋ก์ธ์ค๋ค์ ์๋ก ๊ฒฝ์ ์์ด ๊ฐ์์ ์ฝ์ด์์ ์คํ๋ ์ ์์ต๋๋ค.์์ ํ์ฉ ์ต์ ํ
: 8๊ฐ์ ์ฝ์ด ์ค 4๊ฐ๋ง ์ฌ์ฉ๋๋ฏ๋ก, ๋๋จธ์ง ์ฝ์ด๋ ์์คํ ์ ๋ค๋ฅธ ํ๋ก์ธ์ค๋ ์์ ์ ์ฌ์ฉ๋ ์ ์์ต๋๋ค. ์ด๋ ๋ฉํฐํ์คํน ํ๊ฒฝ์์ ์์คํ ์์์ ํจ์จ์ ์ผ๋ก ํ์ฉํ ์ ์๊ฒ ํด์ค๋๋ค.
(์ฐธ๊ณ ) ๊ทธ๋ผ ์ด๋ป๊ฒ ํด์ผ ๊ฐ์ฉ ์์์ ๋ค ์ธ ์ ์์๊น?
ํ์ด์ฌ์
multiprocessing
๋ชจ๋์ ํ๋ก์ธ์ค๋น CPU ์ฝ์ด ์๋ฅผ ์ง์ ์ง์ ํ๋ ๊ธฐ๋ฅ์ ์ง์ ์ ๊ณตํ์ง ์์ต๋๋ค. CPU ์ฝ์ด์ ํ ๋น๊ณผ ์ค์ผ์ค๋ง์ ์ด์ ์ฒด์ ์ ์์ ์ด๋ฉฐ,multiprocessing
๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ ์ด๋ฌํ ๋ฎ์ ์์ค์ ์์ ๊ด๋ฆฌ์ ์ง์ ๊ฐ์ ํ์ง ์์ต๋๋ค. ๊ทธ๋ฌ๋, ์ ์ฒด CPU ์ฝ์ด๋ฅผ ์ต๋ํ ํ์ฉํ๋ ค๋ ๋ชฉ์ ์ด๋ผ๋ฉด, ์์ ์ ๋ ๋ง์ ํ๋ก์ธ์ค์ ๋ถ๋ฐฐํ๊ฑฐ๋ ์์คํ ์ ๋ณ๋ ฌ ์ฒ๋ฆฌ ๋ฅ๋ ฅ์ ์ต๋๋ก ํ์ฉํ๋ ๋ฐฉ๋ฒ์ ๊ณ ๋ คํ ์ ์์ต๋๋ค. ใ ค ์ ์ฒด CPU ์ฝ์ด ์ฌ์ฉํ๊ธฐ : ์์คํ ์ ์๋ ๋ชจ๋ CPU ์ฝ์ด๋ฅผ ์ฌ์ฉํ๋ ค๋ฉด,multiprocessing.cpu\_count()
ํจ์๋ฅผ ์ฌ์ฉํ์ฌ ์์คํ ์ ์๋ ์ฝ์ด์ ์๋ฅผ ํ์ธํ๊ณ , ์ด๋ฅผPool
์ ์ธ์๋ก ์ฌ์ฉํ ์ ์์ต๋๋ค. ์ด ๋ฐฉ๋ฒ์ ์์คํ ์ ๋ชจ๋ CPU ์ฝ์ด๋ฅผ ํ์ฉํ์ฌ ๋ณ๋ ฌ ์ฒ๋ฆฌ๋ฅผ ์ํํ๋ ค๋ ๊ฒฝ์ฐ ์ ์ฉํฉ๋๋ค. ์๋ ์์๋ฅผ ์ฐธ๊ณ ํด์ฃผ์ธ์ ๐ค
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# ์ ์ฒด CPU ์ฝ์ด ์ฌ์ฉํ๊ธฐ
from multiprocessing import Pool, cpu_count
def my_task(data_chunk):
# ๋ณต์กํ ๊ณ์ฐ ์ํ
result = sum(data_chunk)
return result
if __name__ == "__main__":
data = range(1000000) # ๋๋์ ๋ฐ์ดํฐ
num_cores = cpu_count() # ์์คํ
์ CPU ์ฝ์ด ์ ํ์ธ
chunks = [data[i::num_cores] for i in range(num_cores)] # ๋ฐ์ดํฐ๋ฅผ CPU ์ฝ์ด ์๋งํผ ์ฒญํฌ๋ก ๋๋
with Pool(num_cores) as p: # ์์คํ
์ ๋ชจ๋ CPU ์ฝ์ด ์ฌ์ฉ
results = p.map(my_task, chunks)
๋ฉํฐ์ค๋ ๋ฉ ์์ ํ ๋น ์์
์ด ๋ฉํฐ์ค๋ ๋ฉ ์์์์๋ ์ ์ฒด ์์ ๋ฒ์๋ฅผ 4๊ฐ๋ก ๋๋์ด ๊ฐ ์ค๋ ๋๊ฐ ์ฒ๋ฆฌํ๋๋ก ํฉ๋๋ค. ์ด๋ฌํ ๋ฐฉ์์ ๊ฐ ์ค๋ ๋๊ฐ ์ฒ๋ฆฌํ ๋ฐ์ดํฐ์ ์์ ๋ช ํํ๊ฒ ์ง์ ํ ์ ์๊ธฐ ๋๋ฌธ์, ์์ ์ ๋ถ๋ฐฐ๊ฐ ๊ณ ๋ฅด๊ฒ ์ด๋ฃจ์ด์ง๋๋ก ํ ์ ์์ต๋๋ค.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import threading
def my_task(start, end):
# ๋ฒ์ ๋ด์ ์ซ์ ํฉ๊ณ ๊ณ์ฐ
result = sum(range(start, end))
print(f"Result: {result}")
threads = []
for i in range(4):
# ์ ์ฒด ๋ฒ์๋ฅผ 4๊ฐ์ ๋ถ๋ถ์ผ๋ก ๋๋์ด ๊ฐ ์ค๋ ๋์ ํ ๋น
t = threading.Thread(target=my_task, args=(250000*i, 250000*(i+1)))
threads.append(t)
t.start()
for t in threads:
t.join()
์ ์๋ ์์ ์ฝ๋์์๋ ๊ฐ ์ค๋ ๋๊ฐ ์ฒ๋ฆฌํ๋ ๋ฐ์ดํฐ์ ์์ ๊ท ๋ฑํ๊ฒ ๋ถ๋ฐฐํ์์ต๋๋ค. ์ด๋ ๊ฐ ์์ ๋จ์๊ฐ ๋์ผํ ์์์ ์๋นํ๋ค๊ณ ๊ฐ์ ํ์ ๋ ์ ์ฉํฉ๋๋ค. ํ์ง๋ง ์ค์ ๋ก๋ ์์ ์ ๋ณต์ก๋๊ฐ ๋ค๋ฅผ ์ ์์ผ๋ฏ๋ก, ์์์ ์ธ๊ธํ ๋ฐฉ๋ฒ๋ค์ ํตํด ์์ ๋ถ๋ฐฐ ๋ฐฉ์์ ๋ณด๋ค ์ธ๋ฐํ๊ฒ ์กฐ์ ํ ํ์๊ฐ ์์ต๋๋ค.
์์ ์ ๋ณต์ก๋๋ ์์ ์๋น๋์ ๊ณ ๋ คํ์ฌ ์์ ์ ํ ๋นํ๋ ๊ฒ์ ๋ฉํฐ์ค๋ ๋ฉ ํ๋ก๊ทธ๋จ์ ์ฑ๋ฅ์ ์ต์ ํํ๋ ๋ฐ ์ค์ํ ์์์ ๋๋ค. ๋ฐ๋ผ์, ์์ ์ ํน์ฑ์ ์ ํํ ํ์ ํ๊ณ , ์ด์ ๊ธฐ๋ฐํ ์ ์ ํ ์์ ๋ถ๋ฐฐ ์ ๋ต์ ์ ํํ๋ ๊ฒ์ด ์ค์ํฉ๋๋ค.
(์ฐธ๊ณ ) ๊ทธ๋ ๋ค๋ฉด ์ด๋ป๊ฒ ๋ฉํฐ์ค๋ ๋ฉ ํ๋ก๊ทธ๋จ์ ์ฑ๋ฅ์ ์ต์ ํ๋ฅผ ํ ๊น?
queue๋ฅผ ์ฌ์ฉํด์ task์ ๋ณต์ก๋๋ฅผ ์ ์ํ๊ณ ์ด๋ฅผ args๋ก ๋ฃ์ด์ฃผ๋ฉด ๊ฐ ์ค๋ ๋๊ฐ ์ฒ๋ฆฌํ ๋ฐ์ดํฐ์ ์์ ๋ช ํํ๊ฒ ์ ์ํด์ค ์ ์์ต๋๋ค. (์๋ ์์์ฝ๋ ์ฐธ๊ณ )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
import time
import queue
# ์์
ํจ์
def worker(work_queue):
while not work_queue.empty():
try:
# ํ์์ ์์
์ ๊ฐ์ ธ์ด
task = work_queue.get_nowait()
except queue.Empty:
break
# ์์
์ ๋ด์ฉ(์ฌ๊ธฐ์๋ ๋จ์ํ ์ผ์ ์๊ฐ ๋๊ธฐํ๋ ๊ฒ์ผ๋ก ๊ฐ์ )
print(f"{threading.current_thread().name} is processing task: {task}")
time.sleep(task)
print(f"{threading.current_thread().name} finished task: {task}")
# ์์
์๋ฃ๋ฅผ ํ์ ์๋ฆผ
work_queue.task_done()
# ์์
ํ ์์ฑ ๋ฐ ์์
์ถ๊ฐ
work_queue = queue.Queue()
tasks = [2, 4, 6, 8, 1, 3, 5, 7] # ๊ฐ ์ซ์๋ ์์
์ "๋ณต์ก๋"๋ฅผ ๋ํ๋(์: ์ฒ๋ฆฌ ์๊ฐ)
for task in tasks:
work_queue.put(task)
# ์ค๋ ๋ ์์ฑ ๋ฐ ์์
num_threads = 4
threads = []
for i in range(num_threads):
t = threading.Thread(target=worker, args=(work_queue,))
t.start()
threads.append(t)
# ๋ชจ๋ ์ค๋ ๋์ ์์
์ด ์๋ฃ๋ ๋๊น์ง ๋๊ธฐ
for t in threads:
t.join()
print("All tasks are completed.")