프로세스(Process) vs 스레드(Thread)

박상준·2024년 5월 7일
1

JAVA

목록 보기
4/5
post-custom-banner

프로세스(Process)

  • 정의
    • 프로세스는 실행 중인 프로그램으로, 코드, 힙, 스택 등을 포함한 시스템 자원과 메모리 등의 OS 자원이 할당된 단위이다.
    • 독립적인 메모리 영역(주소공간) 을 가지고, 최소 하나 이상의 스레드를 포함한다.
  • 특징
    • 각 프로세스의 경우 별도의 주소 공간에서 실행되고, 다른 프로세스와 자원을 공유하지 않는다.
    • 프로세스 간 통신 (IPC) 을 통해 데이터를 주고 받을 수 있다.

      IPC 는 서로 다른 프로세스가 데이터를 주고받거나 동기화하는 방법을 의미함.

      각 프로세스는 독립된 메모리 공간을 가지고, 한 프로세스의 데이터를 다른 프로세스가 직접 접근할 수 없음.

      예시로는 세마포어(semaphores), 메시지 큐(Message Queues) 가 있음.

    • OS는 프로세스를 관리하기 위해 프로세스 테이블을 유지한다.

      프로세스 테이블이란

      • OS 가 모둔 실행 중인 프로세스에 대한 정보를 저장하고, 관리하기 위해 사용하는 데이터 구조를 말한다.
      • 컴퓨터에서 프로그램이 실행되면, 해당 프로그램은 프로세스가 되고, OS는 해당 프로세스를 관리하기 위하여 프로세스 테이블에 여러 가지 중요한 정보를 입력함.
        • 다음과 같은 정보 입력
          1. PID(Process ID) : 각 프로세스를 구별하는 고유한 번호
          2. 프로세스 상태 : 실행 중, 대기 중, 준비 완료 등
          3. 등등..

스레드(Thread)

  • 정의
    • 프로세스 내에서 실제로 작업을 수행하는 실행 단위이다.
    • 프로세스 내의 코드, 데이터, 힙 영역을 공유하면서 각자의 스택을 가지고 실행된다.
  • 특징
    • 프로세스 내에 각각의 스택을 가지고 있지만, 나머지 자원은 공유한다
    • 멀티 스레딩을 통해 여러 작업을 병렬로 수행할 수 있어, 자원의 효율적 사용이 가능하다
    • 스레드 간의 컨텍스트 스위칭은 프로세스 간의 컨텍스트 스위칭보다 빠르고 비용이 적게된다.

프로세스와 스레드의 주요 차이점

메모리 공유

  • 프로세스

    • 독립적인 메모리 영역을 가진다.
  • 스레드

    • 프로세스 내에서 메모리(코드, 데이터, 힙)를 공유한다.
    • 이는 가족 구성원들이 집의 공간과 자원을 공유하는 것과 유사하다.

자원간 통신

  • 프로세스
    • 독립적인 메모리 공간, CPU 시간, 파일, 기타 자원을 할당받는다.
    • 다른 프로세스와의 자원 공유는 제한적이고, IPC(Inter-Process Communication) 방식을 통해 이루어진다.
  • 스레드
    • 같은 프로세스 내 스레드들을 메모리 공간, 파일, 기타 특정 자원을 공유합니다.
    • 하지만, CPU 시간은 프로세스 내 스레드들 간 경쟁적으로 할당된다고 합니다.

생성비용

  • 프로세스
    • OS 에 의해 직접적으로 생성된다.
    • 새로운 프로세스를 생성하기 위하여 fork(), create(), spawn() 과 같은 시스템 호출을 이용한다.
  • 스레드
    • 프로세스 내에서 fork(), pthread_create() 와 같은 함수를 통해 생성된다.
    • 이미 생성된 프로세스의 맥락 속에서 스레드를 생성하기에, 프로세스 생성보다 가볍고 효율적이라고 한다.

멀티프로세싱, 멀티스레딩

정의

  • 멀티 프로세싱
    • 여러 개의 프로세스를 동시에 실행하여 시스템 전체의 처리 능력을 향상시키는 기술이다.
    • 각 프로세스는 독립적인 메모리 공간, CPU 시간, 파일 및 기타 자원을 할당받는다.
  • 멀티 스레딩
    • 하나의 프로세스 내에서 여러 개의 스레드를 동시에 실행하여 처리 속도를 높이는 기술이다.
    • 스레드는 프로세스 공간을 공유하지만, CPU 시간은 경쟁적으로 할당된다.

차이점

  1. 자원의 독립성
    • 멀티 프로세스
      • 각 프로세스가 독립된 메모리를 가짐.
    • 멀티스레딩
      • 하나의 프로세스 내의 스레드들이 메모리를 공유
  2. 자원 소모
    • 멀티 프로세싱
      • 더 많은 메모리와 CPU 자원을 소모함.
    • 멀티 스레딩
      • 자원의 효율적 사용
  3. 복잡성과 디버깅
    • 멀티 프로세싱
      • 프로세스 간 통신은 복잡하다
    • 멀티 스레딩
      • 공유 자원으로 인한 동기화 문제와 디버깅의 어려움이 있음.

코드예시

  • 멀티 프로세싱
    • 자바에서는 멀티 프로세싱을.. 구현할 일이 있나 싶다
    • ProcessBuilder 로 외부 프로그램을 프로세스로 올리는 작업을 수행할 수 있다면
    • 사실 코드예시가 별 의미없다.
  • 멀티 스레딩
    • 스프링에서는 기본적으로 멀티 스레딩으로 동작한다.

    • 순수 자바에서는 RunnableCallable , Thread 등으로 구현이 가능하다.

    • 또한 스레드를 매번 생성하는 작업 자체가 비용이 어느정도 필요하기에 미리 ExecutorService 를 통하여 스레드 풀을 미리 생성해 놓는게 성능적으로 유리하다.

    • 이미 생성된 스레드를 통해 병렬적으로 쓰기 작업을 수행하는 코드 예제이다.

      public class MultiThreading {
          
          public static void main(String[] args) {
              try (Writer write = new OutputStreamWriter(System.out, UTF_8)) {
                  ExecutorService availableProcessors = makeMultipleThread();
                  submitTasks(availableProcessors, write);
                  
                  //모든 스레드 작업이 완료될때 까지 기다리고, 스레드풀을 종료한다.
                  availableProcessors.shutdown();
                  availableProcessors.awaitTermination(30, java.util.concurrent.TimeUnit.SECONDS);
                  write.flush();
              } catch (IOException e) {
                  e.printStackTrace();
              } catch (InterruptedException e) {
                  throw new RuntimeException(e);
              }
          }
          
          private static ExecutorService makeMultipleThread() {
              // 현재 시스템의 코어 수만큼 스레드를 생성
              return Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
          }
          
          private static void submitTasks(ExecutorService executorService, Writer os) {
              for (int i = 0; i < 10; i++) {
                  // 스레드 풀에 작업을 제출한다. ( 비동기적으로 콘솔에 출력스트림에 해당 스레드의 이름을 출력한다. )
                  executorService.submit(() -> {
                      try {
                          os.write("Thread Name : " + Thread.currentThread().getName() + "\n");
                      } catch (IOException e) {
                          e.printStackTrace();
                      }
                  });
              }
          }
      }
profile
이전 블로그 : https://oth3410.tistory.com/
post-custom-banner

0개의 댓글