[python] ๋ฉํฐํ๋ก์ธ์ฑ Pool ์ฌ์ฉ๋ฒ ๋ฐ ์ฝ๋ ์์ | multiprocessing.Pool | python ์๋ ํฅ์
๋ฉํฐํ๋ก์ธ์ฑ์ ์ฌ๋ฌ ๊ฐ์ ๋ ๋ฆฝ์ ์ธ ํ๋ก์ธ์ค๋ฅผ ์์ฑํ์ฌ ๊ฐ๊ฐ์ ํ๋ก์ธ์ค๊ฐ ๋ณ๋ ฌ๋ก ์์ ํ๋๋ก ํ๋ ๋ฐฉ์์ด๋ค. ๊ฐ ํ๋ก์ธ์ค๋ ๋ ๋ฆฝ์ ์ธ ๋ฉ๋ชจ๋ฆฌ ๊ณต๊ฐ์ ๊ฐ์ง๋ฉฐ, ํ๋ก์ธ์ค ๊ฐ ํต์ (Inter-Process Co
mvje.tistory.com
์ ํฌ์คํ ์์ ํ์ด์ฌ์ผ๋ก ๋ฉํฐํ๋ก์ธ์ฑ์ ์ฌ์ฉํ๊ธฐ ์ํด multiprocessing.Pool ์ฌ์ฉ๋ฒ์ ๋ํด ์ดํด๋ดค๋ค. ์ด๋ฒ์๋ multiprocessing.Process๋ฅผ ํ์ฉํ ๋ฉํฐํ๋ก์ธ์ฑ ๋ฐฉ๋ฒ๊ณผ Pool, Process ๋ ๊ฐ์ง ๋ฐฉ๋ฒ์ ์ฐจ์ด์ ์ ๋ํด ์์๋ณด๊ณ ์ ํ๋ค.
multiprocessing.Pool๊ณผ multiprocessing.Process๋ ํ์ด์ฌ์ multiprocessing ๋ชจ๋์ ์ฌ์ฉํ์ฌ ๋ฉํฐํ๋ก์ธ์ฑ์ ๊ตฌํํ๋ ๋ ๊ฐ์ง ๋ค๋ฅธ ๋ฐฉ๋ฒ์ผ๋ก, ๊ฐ๊ฐ์ ์ ๊ทผ ๋ฐฉ์์ ํน์ ์ํฉ์ ๋ ํธ๋ฆฌํ๊ฒ ์ฌ์ฉ๋ ์ ์๋ค.
ํนํ ์ฌ๋ฌ ํ๋ก์ธ์ค์ ์๋ก ๋ค๋ฅธ ์์ ์ ํ ๋นํ๊ธฐ ์ํด์๋ multiprocessing.Process๋ฅผ ์ฌ์ฉํ๋ฉด ๋๋ค.
multiprocessing.Pool
- ํธ๋ฆฌํ ์ธํฐํ์ด์ค
- Pool ํด๋์ค๋ฅผ ์ฌ์ฉํ๋ฉด ์ฌ๋ฌ ํ๋ก์ธ์ค๋ฅผ ์ฝ๊ฒ ์์ฑํ๊ณ ๊ด๋ฆฌํ ์ ์์ผ๋ฉฐ
- ๊ฐ ํ๋ก์ธ์ค์ ์์ ์ ๋ถ๋ฐฐํ๊ณ ๊ฒฐ๊ณผ๋ฅผ ์์งํ๋ ๋ฐ ์ ์ฉํ๋ค
- ๋๋ฌธ์ ๊ฐ๋จํ๊ณ ๋์ผํ ์์ ์ ์ฌ๋ฌ ๋ฐ์ดํฐ์ ๋ณ๋ ฌ๋ก ์ ์ฉํด์ผ ํ ๋ ํธ๋ฆฌํ๋ค
- ์์ ๋ถ๋ฐฐ
- map, imap, apply ๋ฑ์ ํตํด ๊ฐ ํ๋ก์ธ์ค์ ๋์ผํ ์์ ์ ๋ณ๋ ฌ๋ก ๋ถ๋ฐฐํ ์ ์๋ค.
- ์ ๋ ฅ ๋ฐ์ดํฐ๋ฅผ ๋๋์ด ์ฒ๋ฆฌํ๊ณ ๊ฒฐ๊ณผ๋ฅผ ์์งํ๋ ๊ณผ์ ์ด ๋ด๋ถ์ ์ผ๋ก ์ฒ๋ฆฌ๋๋ค.
- ํ ํฌ๊ธฐ ์ ์ด
- Pool์ processes ๋งค๊ฐ๋ณ์๋ฅผ ์ฌ์ฉํ์ฌ ์์ฑํ ํ๋ก์ธ์ค์ ๊ฐ์๋ฅผ ์กฐ์ ํ ์ ์๋ค.
# ์ฝ๋ ์์
from multiprocessing import Pool
def square_number(x):
return x ** 2
if __name__ == "__main__":
data = [1, 2, 3, 4, 5]
with Pool(processes=3) as pool:
results = pool.map(square_number, data)
print("Results:", results)
multiprocessing.Process
- ๋ ๋ง์ ์ ์ด
- Process ํด๋์ค๋ฅผ ์ฌ์ฉํ๋ฉด ๊ฐ ํ๋ก์ธ์ค์ ๋ํด ๋ ๋ง์ ์ ์ด๋ฅผ ํ ์ ์๋ค.
- ๊ฐ ํ๋ก์ธ์ค๋ฅผ ๋ช ์์ ์ผ๋ก ์์ํ๊ณ ์ข ๋ฃํ ์ ์๋ค.
- ํ๋ก์ธ์ค ๊ฐ ํต์
- Queue, Pipe ๋ฑ์ ์ฌ์ฉํ์ฌ ํ๋ก์ธ์ค ๊ฐ ๋ฐ์ดํฐ ๊ตํ์ ์ง์ ๊ตฌํํด์ผ ํ๋ค.
- IPC(Inter-Process Communication) ๋ฉ์ปค๋์ฆ์ ํตํด ๋ฐ์ดํฐ๋ฅผ ๊ณต์ ํ ์ ์๋ค.
- ๋ ๋ณต์กํ ์์ ์ ์ ํฉ
- ๋ณต์กํ ์์ ์ด๋ ์๋ก ๋ค๋ฅธ ์์ ์ ๊ฐ ํ๋ก์ธ์ค์ ์ํํ๊ณ ์ ํ ๋ ์ฌ์ฉ๋๋ค๊ณ ํ๋ค.
# ์ฝ๋ ์์ - ๊ธฐ๋ณธ
from multiprocessing import Process, Queue
def square_numbers(numbers, result_queue):
squared_numbers = [x ** 2 for x in numbers]
result_queue.put(squared_numbers)
if __name__ == "__main__":
data = [1, 2, 3, 4, 5]
result_queue = Queue()
# ๊ฐ ํ๋ก์ธ์ค๊ฐ ๋
๋ฆฝ์ ์ผ๋ก ์คํ๋๋ฉฐ, ์๋ก ๋ค๋ฅธ ์์
์ ์ํ
num_of_processes = 3
processes = [Process(target=square_numbers, args=(data, result_queue)) for _ in range(num_of_processes)]
for process in processes:
process.start()
for process in processes:
process.join()
# ๊ฒฐ๊ณผ๋ฅผ ํ์์ ์์ง
results = [result_queue.get() for _ in processes]
print("Results:", results)
- ์ด ์์์์๋ square_numbers ํจ์๊ฐ ๊ฐ๊ฐ์ ํ๋ก์ธ์ค์์ ์คํ๋จ
- ๊ฐ ํ๋ก์ธ์ค๋ ๋ ๋ฆฝ์ ์ผ๋ก data ๋ฆฌ์คํธ์ ์ซ์๋ฅผ ์ ๊ณฑํ๊ณ , ๊ทธ ๊ฒฐ๊ณผ๋ฅผ result_queue์ ๋ฃ์
- ๋ฉ์ธ ํ๋ก์ธ์ค์์๋ ๊ฐ ํ๋ก์ธ์ค์ ๊ฒฐ๊ณผ๋ฅผ ์์งํ์ฌ ์ถ๋ ฅ
# ์ฝ๋ ์์ - ๊ฐ ํ๋ก์ธ์ค์์ ์๋ก ๋ค๋ฅธ ์์ ์ ์ํ
from multiprocessing import Process, Queue
def square_numbers(numbers, result_queue):
squared_numbers = [x ** 2 for x in numbers]
result_queue.put(squared_numbers)
def cube_numbers(numbers, result_queue):
cubed_numbers = [x ** 3 for x in numbers]
result_queue.put(cubed_numbers)
if __name__ == "__main__":
data = [1, 2, 3, 4, 5]
result_queue = Queue()
# ๊ฐ ํ๋ก์ธ์ค์ ๋ค๋ฅธ ํจ์ ํ ๋น
process1 = Process(target=square_numbers, args=(data, result_queue))
process2 = Process(target=cube_numbers, args=(data, result_queue))
# ํ๋ก์ธ์ค ์์
process1.start()
process2.start()
# ํ๋ก์ธ์ค ์ข
๋ฃ ๋๊ธฐ
process1.join()
process2.join()
# ๊ฒฐ๊ณผ๋ฅผ ํ์์ ์์ง
results = [result_queue.get(), result_queue.get()]
print("Squared Results:", results[0])
print("Cubed Results:", results[1])
- ํ๋ก์ธ์ค๋ฅผ ์ฌ๋ฌ๊ฐ ๋ง๋ค๊ณ ๊ฐ ํ๋ก์ธ์ค๋ง๋ค ์๋ก ๋ค๋ฅธ ํจ์๋ฅผ target์ผ๋ก ๋ฃ์ด์ฃผ๋ฉด ๊ฐ ํ๋ก์ธ์ค์์ ์๋ก ๋ค๋ฅธ ํจ์๋ฅผ ์คํํ ์ ์๋ค.
- ์์์์๋ ์ซ์๋ฅผ ์ ๊ณฑํ๋ square_numbers ํจ์์ ์ซ์๋ฅผ ์ธ์ ๊ณฑํ๋ cube_numbers ํจ์๋ฅผ ์๋ก ๋ค๋ฅธ ํ๋ก์ธ์ค๋ก ์คํ