multiprocessing과 ProcessPoolExecutor는 같은 건가요??

조회수 936회

작업 시간을 줄이기 위해 멀티프로세싱을 이용해서 2개 이상의 함수를 동시 실행하는 것을 해보고 있는데, 함수 중간에 리스트 추가나 제외를 하려면 별도의 작업을 통해 메모리 공유를 해준다는 것을 알았습니다.

그래서 그 방법을 찾아보다가 concurrent.futures의 ProcessPoolExecutor라는 것이 멀티프로세싱과 비슷하다는 것을 보았습니다. 그래서 찾아보니 해당 모듈에서 멀티프로세싱 모듈을 사용한다고 나와있는 것을 보았습니다.

그런데 굳이 멀티프로세싱 모듈이 있는데 그걸 실행하는 다른 모듈이 있다는게 약간 이해가 안되고 있습니다.

예제만 보자니 딱히 다른 점이 없는 것 같은데... 별다른 차이가 없는걸 따로 만들었을 리는 없기에 ProcessPoolExecutor 관련 글을 찾아보았는데 이것에 대해 다룬 글들이 많지 않아 부족한 제 머리로는 어떤 차이가 있는지 이해하기 어렵더군요.

혹시 어떤 차이점이 있는지 아시는 분이 계실까 해서 질문합니다.

2 답변

  • 이해의 순서를 반대로 하려고 해서 어려운겁니다.

    먼저 파이썬으 왜 멀티 프로세스 형태로 current 를 구현해야 하는지 이해해야 합니다.

    jvm 이나 clr 등 다른 런타임들이나 언어들은 동시성 구현을 보통 쓰레드를 사용합니다. 쓰레드를 두개 만들어 실행하면 자연스레 코어 두개로 분배되어 실행이 됩니다. 그런데 파이썬은 gc가 레퍼런스 카운팅 모델로 해당 객체에 접근할 때마다 참조 카운트를 가지게 됩니다. 그러다 보니 동시에 여러곳에서 참조를 한다던가 하면 구현도 복잡해지고 성능에서 손해를 봐야 합니다.

    그래서 파이썬에선 GIL 이라는 장치를 마련해두고 파이썬VM 에서 파이썬 객체는 동시에 1개의 쓰레드만 접근 가능하도록 해둔겁니다. 이렇게 하면 싱글쓰레드에서 성능 희생도 없고 구현도 간단해지는 장점이 생깁니다만 8코어 cpu에서 코어를 1개만 사용할 수 있다는 문제가 생깁니다. 파이썬이 1980년대에 개발되었기에 당시에는 프로세서의 코어가 다수개일 수 있다는 고민을 할 시기도 아니었습니다.

    그런데 지금은 멀티코어 시대이고 GO언어 같은 경우는 고루틴으로 엄청 편하게 동시성을 지원합니다.

    그러면 파이썬에서 cpu의 모든 코어를 사용할 수 있는 방법은 없을까...os 에서 프로세스는 독립적이기에 간단하게는 파이썬을 여러개 실행하면 되겠지요. 그것이 multiprocess 모듈로 가능한겁니다. 그런데 단점이 있습니다. 우리는 하나의 프로그램을 단지 모든 코어를 사용해서 수행하고 싶은것이라 변수나 데이터를 서로 공유해야 합니다. 그런데 os에서 프로세스라는 것은 쓰레드와 달리 독립된 공간이기에 프로세스 끼리 서로의 메모리를 침범할 수가 없습니다. 쓰레드라면 변수 공유를 그냥 하면 되는데 프로세스라서 별도의 완전히 독립된 공간이라 변수 공유가 안됩니다.

    그래서 프로세스끼리는 변수, 데이터 공유를 위해서 shared 메모리를 활용하여 이 문제를 해결합니다.

    그런데 각각 독립적인 구조인 멀티프로세스로 동시성을 해결하려다보니 고려할 것도 많고 안정적인 구현도 힘들다보니 고수준의 모듈들이 나오는 겁니다.

    안타깝지만 파이썬은 성능 및 동시성에 대해서 문제가 확실하고 해결하기도 까다롭습니다. 더구나 근래에 멀티코어 시대에 맞는 개발언어와 사용하기 편한 환경이 계속 나오는지라 파이썬의 미래를 낙관하기가 어렵습니다.

    • 코드 구현이 정말 쉽지만 연산 작업이 추가될수록 이런 문제들이 아쉽습니다.. 초보자 2020.12.31 09:21
    • 의견 1. "쓰레드를 두개 만들어 실행하면 자연스레 코어 두개로 분배되어 실행이 됩니다. " 이라고 말씀하셨는데, 제가 알고있는 바로는 쓰레드는 하나의 코어에서 작동하는 것이고, 쓰레드 두개를 코어 두개로 분배시켜 실행시킨다는 것은 잘못된 표현인 것 같습니다. dbwodlf3 2020.12.31 11:04
    • 의견 2. "쓰레드라면 변수 공유를 그냥 하면 되는데 프로세스라서 별도의 완전히 독립된 공간이라 변수 공유가 안됩니다." 이 내용이 앞선 말과 모순되는 것 같습니다. "쓰레드라면 변수 공유를 그냥 하면", 만약 쓰레드가 서로 다른 코어에 분배되어진다면 이것도 멀티 프로세싱과 마찬가지로 shared memory 나 아니면 다른 IPC 방법을 사용해야할 것입니다. dbwodlf3 2020.12.31 11:07
    • 의견 3. "그런데 각각 독립적인 구조인 멀티프로세스로 동시성을 해결하려다보니 고려할 것도 많고 안정적인 구현도 힘들다보니 고수준의 모듈들이 나오는 겁니다. 안타깝지만 파이썬은 성능 및 동시성에 대해서 문제가 확실하고 해결하기도 까다롭습니다. 더구나 근래에 멀티코어 시대에 맞는 개발언어와 사용하기 편한 환경이 계속 나오는지라 파이썬의 미래를 낙관하기가 어렵습니다." 이 내용에 동의하기 어렵습니다. 멀티 프로세싱이 쓰레드 보다 더 쉬우면 쉬웠지, 더 어려울 이유는 없다고 생각합니다. dbwodlf3 2020.12.31 11:07
    • 의견 1의 답변: 정확한 표현으로는 os에서 실행 가능한 쓰레드에 cpu 자원(타임 슬라이스)을 나눠주게 되는 겁니다. 즉 코어가 많으면 자연스레 다수의 코어를 사용하게 됩니다. 결국 멀티코어 cpu에서 "쓰레드를 두개 만들어 실행하면 자연스레 코어 두개로 분배되어 실행이 됩니다." 라는 말은 그렇게 틀린의미가 아니며 GIL 을 가진 python과 다르게 쓰레드를 다수개 만들어서 수행하면 concurrent 하게 수행됨을 설명하기 위함입니다. 정영훈 2020.12.31 22:20
    • 의견2의 답변: 하나의 프로세스에는 다수개의 쓰레드를 가질 수 있고 프로세스내의 쓰레드는 자원을 공유할 수 있습니다. 현대의 os에서 프로세스는 서로 독립된 메모리 구조를 갖기에 기본적으로 변수 공유등이 안되지만 쓰레드는 변수 공유들이 가능합니다. https://mooneegee.blogspot.com/2015/01/os-thread.html 주소를 참고해보시지요 이미지등으로 이해하기 쉽게 설명합니다. 정영훈 2020.12.31 22:30
    • 의견3 의 답변: 동의하기 어려운건 cogi님 자유입니다. 그런데 파이썬의 multiprocess 관련 모듈은 thread 모듈과 달리 새로운 혹은 업데이트된 모듈이 계속 릴리즈 되고 있습니다. 다루기 어렵기 때문에 더 높은 추상화를 제공하기 위함은 아닐까요? process 들이 변수나 데이터를 공유하려면 ipc 등의 방법을 쓰던 shared memory 를 쓰던 뭔가 제3의 방법을 사용해야 하고 관리도 해야 합니다. 이런부분에서 쓰레드가 다루기 쉽다고 생각합니다. 그런데 멀티프로세싱이 멀티쓰레드보다 쉽다는 이유가 무엇인지요? 정영훈 2020.12.31 22:41
    • "멀티프로세싱"이 "멀티쓰레드보다 더 쉽다" 라고 이야기를 한 것이 아니라, "멀티프로세스로 동시성을 해결하려다보니 고려할 것도 많고 안정적인 구현도 힘들다보니" 이렇게 말씀 하시고, "안타깝지만 파이썬은 성능 및 동시성에 대해서 문제가 확실하고 해결하기도 까다롭습니다" 이리 말씀 하시고. "더구나 근래에 멀티코어 시대에 맞는 개발언어와 사용하기 편한 환경이 계속 나오는지라 파이썬의 미래를 낙관하기가 어렵습니다." 이렇게 말씀하신 부분에서. dbwodlf3 2021.1.3 12:49
    • 정영훈님께서 말씀하신 것 처럼 "멀티코어 시대에 맞는 개발언어와 사용하기 편한 환경이 계속 나오는" 인데. 왜 멀티 프로세싱이 쓰레드보다 더 안좋은 것 처럼. 더 어려운 것 처럼 말씀하시는 것이 제가 생각 했을 때에 이해가 되지 않아서. Thread 프로그래밍을 위해서 제공을 해 주는 추상화 정도나, Multiprocessing 프로그래밍을 위해서 제공을 해 주는 추상화 정도나 비슷 하고. 프로그래머가 두 프로그래밍을 하면서 신경써야할 부분은 MultiThread나 Multiprocessing 이나 마찬가지로 산재해 있는데... dbwodlf3 2021.1.3 12:51
    • 정리하자면. 멀티쓰레드나 멀티프로세싱이나 프로그래머 입장에서는 어렵고 쉽고의 문제가 아니라, 각자 장단점이 있는 것 같습니다. 그리고 제 얄팍한 프로그래밍 경험으로는 Multi Thread보다 Multi Processing이 대부분의 문제에서 개인적으로 더 낫다고 생각합니다. dbwodlf3 2021.1.3 12:54
    • 물론 장단점이 있습니다만 멀티프로세싱으로 concurrent 를 구현하면 thread 보다 리소스 낭비가 크게 됩니다. 구체적으로 멀티프로세스 형태 즉 fork를 하게 되면 부모 프로세스의 .code .data 등 메모리 영역을 그대로 복사해서 만들기 때문에 엄청난 낭비인 겁니다. 즉 fork를 10번하면 중복된 영역을 10개 가지게 된다는 겁니다. 낭비죠. 파이썬은 GIL때문에 어쩔 수 없이 멀티프로세싱을 활용하는 형태이지 다른 런타임이나 언어들은 concurrent 구현을 보통 thread 를 활용합니다. 리소스를 적게 차지하고 가볍기 때문입니다. 더구나 하나의 프로세스내 이므로 .code .data 영역들을 공유할 수 있어서 각 thread 간의 변수 및 데이터 공유가 쉽습니다. 이것이 객관적인 겁니다. 물론 객관적인 것을 떠나 개인적으로 더 낫다고 생각하는 것은 자유이긴 합니다. 멀티프로세스가 그나마 나은 점은 데드락은 없을 거라는 겁니다만 데드락은 개발자의 역량 몫이라고 해야 하겠지요. 정영훈 2021.1.3 15:34
    • 이 글에서 말하고 있는 건 '동시성'이 아니라 '병렬성' 같습니다. 파이썬은 블로킹 I/O API를 호출할 때 GIL을 release하기 때문에 멀티스레드를 활용한 동시성 처리는 큰 문제가 없습니다. 또한 코루틴을 이용해 cooperative multitasking 방식의 동시성 처리가 가능해졌기 때문에, 파이썬의 동시성 처리는 상당히 강력합니다. 병렬 처리에서 태생적 한계로 인해 멀티프로세싱을 사용하거나 c 익스텐션을 사용하는 문제가 있다는 점이 문제이기는 하겠습니다. Kyungmin Lee 2021.1.3 17:57
  • The concurrent.futures module provides a high-level interface for asynchronously executing callables.

    multiprocessing is a package that supports spawning processes using an API similar to the threading module.

    1. " 작업 시간을 줄이기 위해 멀티프로세싱을 이용해서 2개 이상의 함수를 동시 실행하는 것을 해보고 있는데. "

    2. " 함수 중간에 리스트 추가나 제외를 하려면 "

    3. " 별도의 작업을 통해 메모리 공유를 해준다는 것을알았습니다. "

    무엇을 하시고자 하시는지 정확히는 모르겠지만, 추측컨데 multiprocessing 을 이용하시면 될 것 같습니다.

    참고.

    https://docs.python.org/3/library/multiprocessing.html#multiprocessing-managers

    • 그 부분이 가장 답답합니다. 더 고수준 인터페이스를 제공한다는데 예제에는 달랑 실행 예제 하나만 있어서요. 초보자 2020.12.30 18:42
    • multiprocessing 의 Manager 을 사용해서 Process 간 Object를 공유한다고 합니다. dbwodlf3 2020.12.30 18:50

답변을 하려면 로그인이 필요합니다.

프로그래머스 커뮤니티는 개발자들을 위한 Q&A 서비스입니다. 로그인해야 답변을 작성하실 수 있습니다.

(ಠ_ಠ)
(ಠ‿ಠ)