본문 바로가기

Python

멀티프로세싱, 멀티스레딩 이해하기 with Python

728x90
반응형

CPU (central processing unit)

  - 명령어를 실행하는 연산 장치

  - 메모리에서 데이터를 읽고 쓰는 등의 계산 작업에 집중

 

메인 메모리

  - 프로세스가 CPU 에서 실행되기 위해 대기하는 곳

 

IO (input/output)

  - 파일을 읽고 쓰거나

  - 네트워크의 어딘가와 데이터를 주고 받는 것

  - 입출력 장치와 데이터를 주거나 받는 것

  - 하드 디스크, 네트워크 카드, 그래픽 카드 등과 관련된 하드웨어 장치가 처리 (CPU가 하지 않음)

 

프로그램

  - 컴퓨터가 실행할 수 있는 명령어들의 집합

 

프로세스

  - 컴퓨터에서 실행중인 프로그램

  - 각각의 프로세스는 독립된 메모리 공간을 할당 받음

  - 명령어들과 데이터를 가짐

  - 프로세스는 한 개 이상의 스레드를 가질 수 있다.

 

스레드

  - 프로세스 내에서 실행되는 작은 실행 단위

  - 프로세스의 자원을 공유하면서 독립적으로 실행

  - 같은 프로세스 내의 스레드들은 같은 메모리 공간을 공유하면서 각각 독립적인 실행 흐름을 가진다.

      - 같은 프로세스의 스레드들끼리 컨텍스트 스위칭은 가볍다. / 같은 프로세스의 스레드들끼리 데이터 공유도 쉽다.

        -> 왜?

         동일 프로세스 내의 스레드 간에는 메모리 상의 코드 영역, 데이타 영역, 힙 영역을 공유 / 스택 영역만 별도로 갖는다.

         (코드 영역: 실행 명령을 포함하는 코드들 / 데이타 영역: Static 변수 혹은 Global 변수,

          힙 영역: 동적 메모리 영역 / 스택 영역: 지역 변수, 매개 변수, 반환값 등 일시적인 데이터)

  - 경량 프로세스(lightweight process)로도 불린다.

  - CPU에서 실행되는 단위 (unit of execution)

      - CPU의 실행 단위는 프로세스였으나, 스레드가 생긴 이후에는 CPU의 실행 단위가 스레드로 바뀜

 

 

단일 프로세스 시스템

  - 한 번에 하나의 프로그램만 실행됨

  - 단점: CPU 사용률이 좋지 않음

        * [연산 작업 -> 입출력 작업 -> 연산 작업] 과 같은 태스크가 있을 때,

          CPU가 연산 작업을 하다가, 입출력 작업은 다른 하드웨어에서 실행하므로,

          다음 연산 작업이 있기 전까지 CPU는 대기하게 된다.

        * 해결책: 여러 개의 프로그램을 메모리에 올려놓고 동시에 실행시키자!

                       IO 작업이 발생하면 다른 프로세스가 CPU에서 실행됨

 

멀티프로그래밍

  - 여러 프로세스가 동시에 메모리에 적재되어 CPU의 사용을 극대화 하는 방식

  - 하나의 CPU가 여러 프로세스를 번갈아가며 실행

  - 단점: CPU 사용 시간이 길어지면 다른 프로세스는 계속 대기

        * 해결책: 프로세스는 한번 CPU를 사용할 때, 아주 짧은 시간(quantum)만 CPU에서 실행되도록 하자

           -> 하나의 CPU가 여러 프로세스를 번갈아가면서 실행: 멀티태스킹

 

멀티태스킹

  - 멀티태스킹은 하나의 시스템(하나의 CPU)에서 여러 작업(여러 프로세스)이 동시에 실행되는 것을 의미

  - 시분할(time-sharing)이나 우선순위에 따라 각 작업에 CPU 시간을 할당하여 빠르게 전환하면서 여러 작업 처리

  - 프로세스의 응답 시간을 최소화 시키는데 목적

  - 단점

    - 프로세서(CPU)가 프로세스를 바꾸는 작업(프로세스의 컨텍스트 스위칭)은 무거운 작업임(오버헤드 발생)

    - 프로세스끼리 데이터 공유가 까다로움

       - 프로세스마다 메모리 상의 독립적인 공간을 가지고 있기 때문에

    -> 코어가 2개 이상이 되면, 각 코어마다 작업을 실행하는게 효율적임

  - 스레드가 생기면서 멀티 태스킹의 의미도 확장

    - 확장된 멀티태스킹 개념: 여러 프로세스와 여러 스레드가 아주 짧게 쪼개진 CPU time을 나눠 갖는 것

 

멀티프로세싱

  - 다수의 CPU가 (다수의 프로세서 또는 코어)가 동시에 다수의 프로세스를 처리하는 시스템

  - 각 프로세서는 독립적으로 실행되며, 서로 통신하여 작업을 조율(IPC를 사용한 통신)

  - 콘텍스트 스위칭 비용이 큼

  -  독립적으로 실행되기 때문에 동기화에 대한 고려가 스레드보다 느슨해도 된다.

 

멀티스레딩

  - 하나의 프로세스 내에서 여러 개의 스레드가 동시에 실행되는 것을 의미

  - 멀티스레딩은 프로세스 간 통신에 비해 경량이며 작은 규모의 작업에서 성능 향상을 가져올 수 있다.

  - 공유되는 자원에 대한 관리를 신경써야 한다. (동기화 작업 매우 신경 써야함) 

 

파이썬의 GIL

Global Interpreter Lock

*CPython으로 구현된 파이썬 경우 GIL로 인해, 파이썬의 CPU 연산은 싱글스레드로 작동

왜?

CPU 연산 작업시 멀티 스레딩은 메모리를 공유하기 때문에 *Race Condition이 발생할 수 있다.

파이썬에서는 이를 막기 위해서 GIL이 있는 것이다.

즉 GIL은 CPU의 연산 작업에서 메모리 자원을 활용하는 것의 사이드 이펙트를 막기 위해 존재

따라서 GIL은 IO 작업 등에서는 작동하지 않아서 IO 작업에는 멀티 스레딩 가능하고,

CPU 연산만 싱글스레드로 작동

 

CPU 연산을 그럼 병렬적으로 여러개는 아예 못할까?

아니다. 할 수 있다. 이 때는 멀티스레드 대신에 멀티프로세스 활용

멀티스레드는 안되면서 멀티프로세스는 왜 될까?

프로세스들은 몇개가 실행되든 각각 독립된 메모리 공간을 점유하고 활용.

따라서 메모리 관리 역시 독립적으로 되기 때문에 race condition 문제가 발생하지 않아서

GIL이 멀티프로세스를 막을 이유가 없기 때문에 Python에서 멀티프로세싱은 가능

단. 멀티프로세스 자체가 무거운 작업이기 때문에 주의를 갖고 사용해야됨

 

스레드와 프로세스의 사용 예시

with concurrent.futures.ThreadPoolExecutor(max_workers=5) as executor:
	...
    
with concurrent.futures.ProcessPoolExecutor(max_workers=5) as executor:
	...

위와 같이, 스레드를 사용할 것인지, 프로세스를 사용할 것인지 선택 가능

 

 

* Race Condition

레이스 컨디션(Race Condition)은 동시에 둘 이상의 스레드가 공유된 자원에 접근하려고 할 때 발생하는 문제

이러한 상황에서 어떤 스레드가 먼저 해당 자원을 변경하면

다른 스레드의 작업 결과가 예측 불가능하게 변경될 수 있다.

 

 

Python 구현체 (인터프리터)

CPython (Default Python Implementation):
설명: CPython은 파이썬의 기본 및 표준 구현체로 C 언어로 작성
GIL 사용 여부: 사용
대안: GIL로 인한 성능 문제를 해결하려면 멀티프로세싱을 사용하거나, C 확장 모듈이나 외부 프로세스를 활용

* 다른 구현체 들은 GIL을 적용하지 않고 다른 방식의 메모리 관리 모델을 적용

 

Jython (Python for Java):
설명: Jython은 JVM(Java 가상 머신)에서 실행되는 파이썬 구현체로, 자바와의 통합성을 제공
GIL 사용 여부: 미사용
대안: JVM이 멀티스레딩을 처리

 

IronPython (.NET Framework):
설명: IronPython은 .NET Framework에서 동작하는 파이썬 구현체로, .NET 언어들과의 상호 운용성을 제공
GIL 사용 여부: 미사용
대안: .NET CLR이 멀티스레딩을 처리

 

PyPy (Python in Python):
설명: PyPy는 JIT(Just-In-Time) 컴파일러를 사용하여 파이썬 코드를 실행하며, 성능 최적화에 중점을 둔 구현체
GIL 사용 여부: 미사용
대안: JIT 컴파일러를 통해 GIL이 없는 새로운 메모리 관리 모델을 도입함으로써 GIL을 피하고 성능을 향상

 

MicroPython:
설명: MicroPython은 임베디드 시스템에서 동작하는 경량 파이썬 구현체로, 리소스가 제한된 환경을 위해 최적화
GIL 사용 여부: 미사용
대안: 리소스가 제한된 환경에서의 동작을 고려하여 GIL이 없는 구현체로 설계

 

출처 및 참고 자료:

https://www.youtube.com/watch?v=QmtYKZC0lMU

https://inpa.tistory.com/entry/%F0%9F%91%A9%E2%80%8D%F0%9F%92%BB-multi-process-multi-thread

https://www.youtube.com/watch?v=1grtWKqTn50

https://www.youtube.com/watch?v=sJAcnXquSd4

728x90
반응형