Dev

Process와 Thread. 다다익프? 다다익쓰?

친환경사과 2023. 4. 3. 14:15

 

🍎 크롤링 애플리케이션을 개발하던 중 병렬 처리를 위해 Multi Process와 Multi Thread를 사용했습니다. 몇 개의 Process와 Thread를 사용해야 효율이 좋을지 고민이 생겼습니다. 고민을 해결하기 위해 Process와 Thread를 알아보고 사용 시 주의사항을 알아보는 블로그 글입니다.


🍏 본격적으로 들어가기 전 Processd와 Thread에 관련해 가볍게 정리합니다.

  • Process : Process는 실행 중인 프로그램의 인스턴스이며, 자신만의 독립적인 메모리 공간과 실행 컨텍스트를 갖습니다. 각각의 프로세스는 OS에 의해 별도의 프로세스 ID(PID)가 할당되며, 각각의 프로세스는 자신만의 실행 스레드를 가질 수 있습니다. 여러 프로세스는 서로 독립적이기 때문에 서로의 메모리에 직접 접근할 수 없습니다.
  • Thread : 스레드는 한 프로세스 내에서 실행되는 하나의 실행 흐름입니다. 하나의 프로세스는 여러 개의 스레드를 가질 수 있으며, 각각의 스레드는 동일한 메모리 공간을 공유합니다. 이는 각각의 스레드가 서로 다른 작업을 동시에 수행할 수 있도록 합니다.

➕ 일반적으로, 멀티 스레딩 프로그램은 멀티 프로세싱 프로그램보다 더 효율적이며 빠르게 동작할 수 있습니다. 이유는 멀티 스레드 프로그램에서 각 스레드가 공유하는 메모리 영역을 효율적으로 활용할 수 있기 때문입니다.

➕ 프로세스와 스레드의 Context Switching의 공통점은 커널 모드에서 실행, CPU의 레지스터 상태를 교체하는 것입니다.


❓Process는 어떤 동작 과정을 거치나요?

  1. 작업을 실행할 적절한 프로세스를 선택합니다. 이 선택은 OS 스케줄링 알고리즘에 의해 이루어집니다.
  2. 선택된 프로세스가 메모리에 로드되어 있지 않은 경우, OS는 해당 프로세스를 메모리에 로드합니다. 이 과정은 프로세스의 실행 파일을 메모리로 복사하는 것으로 이루어집니다.
  3. 프로세스가 메모리에 로드된 후에는, OS는 프로세스를 초기화하고 시작합니다. 이 과정은 프로세스의 코드와 데이터를 초기화하고, 스택과 힙 영역을 설정하는 것으로 이루어집니다.
  4. 프로세스가 실행 중일 때, OS는 해당 프로세스의 상태를 추적하고, 필요한 경우에는 스케줄링 알고리즘을 사용하여 프로세스의 실행을 일시 중지하고 다른 프로세스를 실행시킵니다.
  5. 작업이 완료되면, 해당 프로세스는 종료되고, 메모리에서 제거됩니다.
    위 과정은 OS가 효율적으로 프로세스 작업을 관리하고 실행할 수 있도록 해줍니다.

 

❓Thread 어떤 동작 과정을 거치나요?

  1. 스레드 생성 : 스레드가 생성되면, OS는 해당 스레드에 대한 고유한 스레드 ID를 할당합니다.
  2. 스케줄링 : 생성된 스레드는 스레드 스케줄러에 의해 실행 대기열에 추가됩니다. 스케줄러는 실행할 스레드를 선택하기 위해 스케줄링 알고리즘을 사용합니다.
  3. CPU 할당 : 스케줄러는 실행 대기열에서 다음에 실행될 스레드를 선택하고 해당 스레드에 CPU를 할당합니다. 스레드는 CPU를 할당받으면 실행 상태(Running State)로 전환됩니다.
  4. 작업 수행 : 스레드는 할당받은 작업을 수행합니다. 이 때, 스레드는 자신만의 스택과 레지스터를 갖고 작업을 처리합니다. 스레드는 작업을 수행하는 도중에 다른 스레드로 전환될 수 있습니다.
  5. 작업 완료 : 스레드가 작업을 완료하면, OS는 해당 스레드를 실행 종료(Exit) 상태로 전환합니다. 이 때, 스레드가 생성한 자원을 해제하고, 다른 스레드에게 자원을 반환해야 합니다.
  6. 스레드 종료 : 스레드가 실행 종료되면, 해당 스레드의 자원을 해제하고, OS는 해당 스레드의 스레드 ID를 반환합니다.

 

❓Process와 Thread 둘 다 많으면 많을수록 좋은게 아닌가요?

  • 아닙니다. 프로세스와 스레드가 많으면 항상 좋은 것은 아닙니다. 프로세스와 스레드를 생성하면 시스템 자원을 소비하므로, 많은 프로세스와 스레드가 있다면 CPU, 메모리, 디스크 등의 자원 사용량이 증가하게 됩니다. 이는 자원의 한계를 초과할 경우 시스템이 느려지거나 멈추는 등의 문제가 발생할 수 있습니다.
  • 스레드는 하나의 프로세스 내에서 동시에 실행되는 작업 단위입니다. 스레드는 서로 공유하는 자원에 대한 동기화 문제가 발생할 수 있으며, 이로 인해 프로세스의 성능이 저하될 수 있습니다. 또한 스레드를 사용하는 경우, 스레드 간의 경쟁이 발생하게 되는데, 이는 다중 스레드 환경에서 발생하는 경쟁 조건 문제를 야기할 수 있습니다.

🍏 프로세스의 경우 프로그램을 많이 실행시켰을 때 컴퓨터가 느려지는 것을 직접적으로 경험한 적이 많아 이해하기 어렵지 않았습니다. 반면, 프로세스 내부에 존재하는 스레드의 경우 프로세스 보다 경험이 드물어 더 깊게 알아볼 필요가 있습니다.

 

 

❓Multi Thread를 사용할 때 성능 저하 요인은 어디에 있나요?

  • 스레드의 숫자가 너무 많아지면 Context Switching Overhead, 자원 경합, 메모리 사용량 때문에 오히려 성능이 저하될 수 있습니다.
  • Context Switching 오버헤드 : 스레드 숫자가 많아지면, 스레드 간의 Context Switching이 더 자주 발생합니다. 이는 프로세서의 성능을 저하시키는 오버헤드를 유발할 수 있습니다. Context Switching 작업은 오버헤드가 큰 작업 중 하나입니다. 이는 스레드의 상태를 저장하고 복원하는 데 걸리는 시간과 함께, CPU 캐시에 저장된 데이터를 지워야 하기 때문입니다. 이는 Cache miss가 발생하여 메모리 접근 시간이 길어지게 되어 CPU 성능을 저하시킵니다.
    • Context Switching은 여러 프로세스/스레드를 동시에 실행시키기 위해 필요합니다.
  • 자원 경합 : 스레드의 숫자가 많아지면, 공유 자원에 대한 경합이 더 심해집니다. 이는 Lock 등의 동기화 기법을 사용하여 해결할 수 있지만, 이를 위해 더 많은 CPU 자원이 필요합니다.
  • 메모리 사용량 : 스레드의 숫자가 많아지면, 각 스레드마다 스택 메모리를 할당해야 합니다. 이는 전체 메모리 사용량을 증가시키는데, 메모리 부족으로 인한 성능 저하가 발생할 수 있습니다.

📝 결과

  • 적절한 프로세스 개수와 스레드 수를 결정하기 위해선 사용하고 있는 컴퓨터의 조건을 생각해 결정해야합니다. 모든 컴퓨터가 각자 다른 스펙을 갖고 있기 때문에 환경에 알맞는 프로세스, 스레드 수는 다릅니다.
  • 크롤링 애플리케이션 병렬 처리를 진행할 때도 적절한 프로세스, 스레드 수는 매 번 숫자를 바꿔 진행한 실험을 통해 알 수 있었습니다. 

📚 Reference

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