๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
๐Ÿ’ป Programming/Python

[python] ๋ฉ€ํ‹ฐํ”„๋กœ์„ธ์‹ฑ Process ์‚ฌ์šฉ๋ฒ• ๋ฐ ์ฝ”๋“œ ์˜ˆ์‹œ | multiprocessing.Process | ์—ฌ๋Ÿฌ ํ”„๋กœ์„ธ์Šค์— ์„œ๋กœ ๋‹ค๋ฅธ ์ž‘์—…์„ ํ• ๋‹น

by ๋ญ…์ฆค 2024. 1. 7.
๋ฐ˜์‘ํ˜•
 

[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 ํ•จ์ˆ˜๋ฅผ ์„œ๋กœ ๋‹ค๋ฅธ ํ”„๋กœ์„ธ์Šค๋กœ ์‹คํ–‰

 

๋ฐ˜์‘ํ˜•