ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 파이썬: 멀티쓰레딩(Threading)과 멀티프로세싱(multiprocessing)
    금융퀀트/프로그램기초 2024. 3. 16. 09:13
    반응형

    파이썬의 GIL(Global Interpreter Lock)

    파이썬 프로그램의 실행 구조는 아래 그림 1과 같다. 여기서 프로세스는 하나의 실행 중인 프로그램을 의미하고, 프로세스 안에서 일어나는 작업의 단위들을 쓰레드라고 한다. 파이썬에서는 기본적으로 하나의 프로세스는 하나의 코어를(Core) 사용하고 multiprocessing 라이브러리를 사용하면 여러 개의 코어를 사용하여 작업이 가능하다.

    그림1: 파이썬의 코드실행 구조

    우리같은 비전문가는 보통 보급형 "Intel(R) Core(TM) i5-9400 CPU @ 2.90GHz" CPU를 사용하고 이 CPU에는 6개의 코어가 달려있기 때문에 멀티프로세스 작업을 6개를 초과해서 수행하면 작업 효율이 더 크게 증가하지는 않는다.

    그림2: CPU사양 확인

    그리고 파이썬에서는 하나의 프로세스 안에서는 여러 개의 쓰레드가 동시에 수행될 수 없다. 위 그림 1처럼 하나의 쓰레드가 수행되고 있으면 나머지 쓰레드는 실행 중인 쓰레드 뒤에서 대기하고 있는 형태가 되는 것이다. 프로세스 내부의 이런 작업구조를 GIL(Globla Interpreter Lock)이라고 한다. 파이썬에서 multithread를 지원하는 라이브러리가 있는데, 이는 I/O바운드 작업(In/Out: 읽기, 쓰기, 네트워크 작업 등)에서 대기시간을 이용하는 것이다. multithread를 사용하지 않으면 요청, 대기, 응답 완료 후 다음 작업을 수행한다면, multithread를 통해서 요청만 순서대로 처리하고, 응답이 완료되는 순으로 결과를 처리할 수 있는 것이다.

    멀티쓰레딩 기본적인 구현

    멀티쓰레딩은 threading이라는 라이브러리를 이용해서 아래와 같이 쉽게 구현할 수 있다. 먼저 import threading을 이용해서 threading 라이브러리를 가져온다. threading의 Thread 클래스와 print_korean 함수를 참조해서 thread1, print_numbers 함수를 참조해서 thread2를 만든 뒤 작업을 수행하면 결과를 확인할 수 있다.

    import threading
    import time
    
    # 쓰레드로 실행될 함수 정의
    def print_korean():
        data=["가", "나"]
        for i in data:
            print(f"Process: {i}")
            # 0.5초 대기
            time.sleep(0.5)
    def print_numbers():
        for i in range(3):
            print(f"Process: {i}")
            # 0.1초 대기
            time.sleep(0.1)
    # 메인 시작
    print("멀티쓰레드 시작!")
    # 멀티쓰레드 생성
    thread1 = threading.Thread(target=print_korean)
    thread2 = threading.Thread(target=print_numbers)
    # 멀티쓰레드 시작
    thread1.start()
    thread2.start()
    # 스레드가 종료될 때까지 대기
    thread1.join()
    thread2.join()
    # 메인 종료
    print("멀티쓰레드 종료!")

     
    위 코드에 따라서 아래와 같은 결과가 나온다.

    그림3: 멀티쓰레딩 코드실행 결과

    멀티프로세싱 기본적인 구현

    멀티프로세싱은 multiprocessing 이라는 라이브러리를 통해서 구현이 가능하다. 먼저 from multiprocessing import Process를 이용해서 Process 클래스를 가져온다. Process 클래스와 print_korean 함수를 참조해서 process1, print_numbers 함수를 참조해서 process2를 만든 뒤 작업을 수행하면 결과를 확인할 수 있다.

    from multiprocessing import Process
    import time
    
    # 프로세스로 실행될 함수 정의W
    def print_korean():
        data=["가", "나"]
        for i in data:
            print(f"Process: {i}")
            # 0.5초 대기
            time.sleep(0.5)
    def print_numbers():
        for i in range(3):
            print(f"Process: {i}")
            # 0.1초 대기
            time.sleep(0.1)
    # Windows에서 python multiprocessing을 위해선 if __name__=="__main__":이 필요
    if __name__=="__main__":
        # 메인 시작
        print("멀티프로세스 시작!")
        # 멀티프로세스 생성
        process1 = Process(target=print_korean)
        process2 = Process(target=print_numbers)
        # 멀티프로세스 시작
        process1.start()
        process2.start()
        # 스레드가 종료될 때까지 대기
        process1.join()
        process2.join()
        # 메인 종료
        print("멀티프로세스 종료!")

    위 코드에 따라서 아래와 같은 결과가 나온다. 

    그림3: 멀티프로세싱 코드실행 결과

     

    반응형
Designed by Tistory.