λ©ν°νλ‘μΈμ±μ μ¬λ¬ κ°μ λ 립μ μΈ νλ‘μΈμ€λ₯Ό μμ±νμ¬ κ°κ°μ νλ‘μΈμ€κ° λ³λ ¬λ‘ μμ νλλ‘ νλ λ°©μμ΄λ€. κ° νλ‘μΈμ€λ λ 립μ μΈ λ©λͺ¨λ¦¬ 곡κ°μ κ°μ§λ©°, νλ‘μΈμ€ κ° ν΅μ (Inter-Process Communication, IPC) λ©μ»€λμ¦μ ν΅ν΄ λ°μ΄ν°λ₯Ό κ΅νν μ μλ€.
νμ΄μ¬μμ λ©ν°νλ‘μΈμ±μ ꡬννκΈ° μν΄ μ¬μ©λλ μ£Όμ λͺ¨λμ multiprocessingμ΄λ€. multiprocessing λͺ¨λμ νμ΄μ¬μμ λ€μ€ νλ‘μΈμ€λ₯Ό μ¬μ©νμ¬ λ³λ ¬ μμ μ μννλ λ° λμμ΄ λλ λꡬλ₯Ό μ 곡νλλ°, threading λͺ¨λκ³Ό λ¬λ¦¬ Global Interpreter Lock (GIL)μ μν₯μ λ°μ§ μμΌλ―λ‘ CPU-bound μμ μ ν¨κ³Όμ μ΄λ€.
multiprocessing.Pool
multiprocessing.Pool ν΄λμ€λ λ©ν°νλ‘μΈμ±μ μ½κ² ꡬνν μ μλλ‘ λμμ£Όλ ν΄λμ€λ‘, κ°λ¨ν μ½λλ‘ μ¬λ¬ μμ
μ λ³λ ¬λ‘ μ€νν μ μλ€. Pool ν΄λμ€λ μ¬λ¬ νλ‘μΈμ€λ₯Ό μμ±νκ³ κ΄λ¦¬νλ©°, μμ
μ μ΄λ€ νλ‘μΈμ€μ λΆμ°νμ¬ μ²λ¦¬νλ€.
Pool ν΄λμ€μ μ€μν λ©μλ μ€ νλλ map λ©μλμΈλ°, μ΄λ μ
λ ₯ λ°μ΄ν°λ₯Ό μ¬λ¬ νλ‘μΈμ€μ λΆμ°νκ³ κ°κ°μ νλ‘μΈμ€μμ μ£Όμ΄μ§ ν¨μλ₯Ό μνν ν κ²°κ³Όλ₯Ό μμ§νλ μν μ νλ€. κ° μ
λ ₯μ λν κ²°κ³Όλ μ
λ ₯ μμλλ‘ λ°νλλ€.
multiprocessing.Pool(processes=None, initializer=None, initargs=())
- processes: μμ±ν νλ‘μΈμ€μ κ°μ. κΈ°λ³Έκ°μ CPU μ½μ΄μ κ°μ
- initializer: κ° νλ‘μΈμ€κ° μμλ λ νΈμΆν μ΄κΈ°ν ν¨μ
- initargs: μ΄κΈ°ν ν¨μμ μ λ¬ν μΈμλ€μ νν
pool.map(func, iterable, chunksize=None)
- func: κ° μ λ ₯μ λν΄ μ€νν ν¨μ
- iterable: ν¨μμ μ λ¬ν μ λ ₯ λ°μ΄ν°
- chunksize: κ° νλ‘μΈμ€μ ν λΉλλ λ°μ΄ν° λ¬Άμμ ν¬κΈ°. ν¬κΈ°κ° μμμλ‘ μμ λ©μ΄λ¦¬λ‘ λλμ΄μ§λ©°, μ΄λ μμ μμ λ€μ΄ λΉ λ₯΄κ² μλ£λ λ μ μ©νλ€.
λ©ν°νλ‘μΈμ± μ½λ μμ
# multiprocessing.Pool
from multiprocessing import Pool
def my_function(arg):
result = arg ** 2
print(f"Result: {result}")
return result
if __name__ == "__main__":
with Pool(processes=4) as pool:
inputs = [1, 2, 3, 4, 5]
results = pool.map(my_function, inputs)
print("Results:", results)
- λ©ν°νλ‘μΈμ±μΌλ‘ μ€ννκ³ μ νλ ν¨μλ₯Ό μμ±(my_function)
- multiprocessing.Poolμ λ§λ€κ³
- μ€ννκ³ μ νλ ν¨μμ iterableν μ λ ₯ λ°μ΄ν°λ₯Ό pool.mapμ ν΅ν΄ μ λ ₯
# μ±κΈ νλ‘μΈμ€ vs λ©ν° νλ‘μΈμ€ μλ μΈ‘μ
import multiprocessing
import time
def my_function(number):
result = 1
for _ in range(number):
result = result ** 2
return result
def run_single_process(number):
start_time = time.time()
for _ in range(number):
my_function(number)
end_time = time.time()
elapsed_time = end_time - start_time
print(f"Single process - Elapsed Time: {elapsed_time} seconds")
def run_with_multiprocessing(number, num_processes):
start_time = time.time()
with multiprocessing.Pool(processes=num_processes) as pool:
pool.map(my_function, [number] * num_processes)
end_time = time.time()
elapsed_time = end_time - start_time
print(f"With multiprocessing - Elapsed Time: {elapsed_time} seconds")
if __name__ == "__main__":
number_to_process = 1000
num_processes = 4
print("Running with single process:")
run_single_process(number_to_process)
print("\nRunning with multiprocessing:")
run_with_multiprocessing(number_to_process, num_processes)
- μ μ½λλ₯Ό μ¬μ©νλ©΄ κ°λ¨ν ν¨μλ₯Ό λ©ν°νλ‘μΈμ±μΌλ‘ μ€ννμ λμ μ±κΈ νλ‘μΈμ€λ‘ μ€ννμ λμ μλλ₯Ό μΈ‘μ ν μ μλ€
- κ²°κ³Όλ₯Ό 보면 λ©ν° νλ‘μΈμ±μ μ¬μ©νμ λ μ²λ¦¬ μκ°μ΄ ν¨μ¬ λΉ λ₯Έ κ²μ λ³Ό μ μλ€
μλ ν¬μ€ν μμλ multiprocessing.Processμ νμ©ν λ©ν°νλ‘μΈμ±κ³Ό Pool, Process ν΄λμ€μ μ°¨μ΄μ μ λν΄ μ΄ν΄λ³Έλ€. νΉν Processλ₯Ό μ¬μ©νλ κ²½μ° μ¬λ¬ νλ‘μΈμ€μ μλ‘ λ€λ₯Έ μμ μ ν λΉν μ μλ€.