Program과 Process와 Thread

7 minute read

Summary

프로그램과 프로세스와 스레드의 차이를 알아본다.

프로그램(Program)

컴퓨터에 어떤 작업을 위해 실행할 수 있는 파일

  • 예) chrome.exe, notepad.exe1 notepad.exe

    • 참고: 권한이 있다면, Linux에서는 아무 파일이나 실행 가능하다.2
      윈도우랑 달리, 리눅스는 파일 확장자 바탕으로 실행 파일의 기준을 나누지 않는다.3 .sh확장자가 있거나 없거나 실행할 파일의 경로로 명령어를 실행할 수 있다. 예를 들어, 실행할 파일이 현재 디렉터리에 있다면, .testscript.sh와 같은 커맨드로 실행 할 수 있다.
  • 프로그램은 컴퓨터의 주기억(primary memory)장치가 아닌 보조기억(secondary memory)장치에 저장된다. 프로그램이 주기억장치로 읽히고 커널에 의해 실행된다.
  • 사용자가 프로그램을 실행하면, 운영체제(OS)가 프로세스를 만들어 프로그램을 실행시킨다.

  • 보조기억장치에 상주하기 때문에 ‘passive entity’라고도 불린다.
  • 1개의 프로그램은 1개 이상의 프로세스를 가질 수 있다.

프로세스(Process)

프로그램의 실행된 인스턴스 또는 실행 중인 프로그램
디스크로부터 메모리에 적재되어 CPU의 할당을 받을 수 있는 것 (독립적인 개체)

process image 4

  • 운영체제로부터 시스템 자원을 할당받음
    • 할당받는 시스템 자원: CPU 시간, 주소 공간, Code, Data, Stack, Heap의 구조로 되어 있는 독립된 메모리 영역
  • 각 프로세스는 독립된 메모리 영역(Code, Data, Stack, Heap의 구조)을 할당받는다.
    • 기본적으로 프로세스당 최소 1개의 스레드(메인 스레드)를 가지고 있다.
    • 각 프로세스는 별도의 주소 공간에서 실행되며, 한 프로세스는 다른 프로세스의 변수나 자료구조에 접근할 수 없다.
    • 한 프로세스가 다른 프로세스의 자원에 접근하려면 프로세스 간의 통신(IPC, inter-process communication)을 사용해야 한다.
      • 다른 메모리 주소를 사용하기 때문에 느리다.
      • 예) 파이프, 파일, 소켓 등을 이용한 통신 방법 이용
    • 프로세스 스택: 함수의 매개변수, 복귀 주소, 로컬 변수와 같은 임시 자료
    • 데이터 섹션: 전역 변수들을 수록함
    • 힙: 프로세스 실행 중에 동적으로 할당되는 메모리 (“new”)
  • ‘job,’ ‘task,’ ‘active entity’라고도 불린다.
    • 프로세스는 주기억장치에 상주하고, 시스템이 리부트되면 주기억장치에서 사라진다.
  • 1개의 프로세스는 1개 이상의 스레드를 가질 수 있다.

프로세스 생성과 종료

프로세스는 프로세스에 의해 생성된다. 컴퓨터 부팅 시 운영체제가 메모리에 올라온다. 운영체제가 처음으로 하는 일은 최초의 프로세스를 생성하는 것이다. 최초의 프로세스가 다른 프로세스를 만들고, 이 프로세스가 또 다른 프로세스를 만든다.

최초의 프로세스 이름은 운영체제마다 다르다. Unix 운영체제에서는 최초의 프로세스를 Init이라고 한다.5

  • 프로세스 생성
    • fork(): 새로운 프로세스를 만드는 시스템 콜
    • exec(): 만들어진 프로세스에서 파일을 실행할 때 쓰는 시스템 콜
  • 프로세스 종료
    • exit(): 프로세스를 종료하는 시스템 콜
    • 한 프로세스가 종료되면 해당 프로세스가 사용한 모든 자원(메모리, 파일, I/O)은 회수되어야 한다. 회수된 자원과 권한은 모두 운영체제로 되돌아가야 한다.

프로세스 상태

process state 6

  • New: 프로세스가 생성 중이다.7
    • 프로세스가 생성 되었지만 아직 OS의 승인(admit)을 받지 못한 상태8
  • Ready: 프로세스가 할당되기 위해 기다린다.
    • 할당된 프로그램이 실행되기 위한 모든 준비(초기화)를 마친다. Running 할 준비가 되어 있다.
    • New 상태에서 승인(admit)된 상태. CPU를 제외한 다른 자원 준비 완료.
    • 보조기억장치에 있는 프로그램을 실행시켜 메모리에 로드된 상태
  • Running: CPU가 해당 프로세스를 실행한다. 명령어들이 실행된다.
    • 프로세스가 CPU를 할당받아 실제로 수행되고 있다.
  • Waiting: 프로세스가 어떤 이벤트가 일어나기를 기다린다(Blocked).
    • 프로세스가 끝나지 않은 시점에서 I/O나 다른 이벤트로 인해 CPU를 사용하지 않고 다른 작업을 한다.
    • 프로세스가 running하다가 할당받은 CPU를 반납하고, I/O 작업 완료를 기다리는 것 같은 특별한 이벤트를 기다린다.
    • 해당 작업이 끝나면 다시 CPU에 의해 실행될 수 있도록 Ready상태로 돌아가야한다.
  • Terminated: 프로세스가 실행을 끝내고 완전히 종료된다.

프로세스 전이동작

  • admit(new -> ready): OS에 의해 프로세스를 승인
  • dispatch(ready -> running): 처리기가 프로세스를 수행하기 위해 CPU할당. 시간도 할당.
  • interrupt(running -> ready): 할당된 시간이 지나면 time out interrupt가 발생. CPU는 다른 프로세스를 실행시킴.
  • event wait(running -> waiting): time out 전에 I/O 요청이 발생(sleep, block)
  • event completion(waiting -> ready): I/O요청이 완료되면 다시 ready 상태로 전이.
  • exit(running -> terminated, ready -> terminated, waiting -> terminated): 프로세스 종료

프로세스 제어 블록(Process Control Block, PCB)

특정 프로세스에 대한 중요한 정보를 저장 하는 운영체제의 자료구조4

PCB 7

  • 운영체제는 프로세스를 관리하기 위해 프로세스의 생성과 동시에 고유한 PCB를 생성한다.
  • Task Control Block(TCB)라고도 한다.
  • 프로세스 작업의 진행 상황이 모두 PCB에 저장된다.
    • 프로세스는 CPU를 할당받아 작업을 처리하다가도 프로세스 전환이 발생하면 진행하던 작업을 저장하고 CPU를 반환해야 하는데, 이때 작업 진행 상황을 PCB에 저장한다.
    • 다시 CPU를 할당받게 되면 PCB에 저장되어 있던 내용을 불러와 이전에 종료됐던 시점부터 다시 작업을 수행한다.
  • PCB에 저장되는 정보
    • 프로세스 식별자(Process ID, PID) : 프로세스 식별번호
    • 프로세스 상태 : new, ready, running, waiting, terminated 등의 상태를 저장
    • 프로그램 카운터 : 프로세스가 다음에 실행할 명령어의 주소
    • CPU 레지스터
    • CPU 스케쥴링 정보 : 프로세스의 우선순위, 스케줄 큐에 대한 포인터 등
    • 메모리 관리 정보 : 페이지 테이블 또는 세그먼트 테이블 등과 같은 정보를 포함
    • 입출력 상태 정보 : 프로세스에 할당된 입출력 장치들과 열린 파일 목록
    • 어카운팅 정보 : 사용된 CPU 시간, 시간제한, 계정번호 등

프로세스 큐(Queue)

프로세스는 수행하면서 상태가 여러 번 변하고 상태에 따라 서비스를 받아야 하는 곳이 다르다. 일반적으로 프로세스는 여러 개가 한 번에 수행 되므로 이에 따른 순서가 필요하다. 이러한 순서를 대기하는 곳을 큐라고 한다. 큐에는 Job, Ready, Device queue 가 있다.

자세한 내용은 스케줄러 포스트를 참고하면 된다.

스레드(Thread)

프로세스의 실행 단위
프로세스 내에서 실행되는 여러 흐름의 단위
프로세스가 할당받은 자원을 이용하는 실행의 단위

thread image 1 1

  • 예) 사용자가 메모장을 실행하면, 운영체제가 프로세스를 만들고 그 프로세스의 메인스레드를 실행시킨다.
  • 프로세스의 특정한 수행 경로
    • 각 스레드는 각자의 태스크와 각자의 프로세스 내 실행경로를 가지고 있다.
    • 예) 메모장 프로그램에서 한 스레드는 사용자 입력을 받고 다른 스레드는 문서를 출력한다.

thread image 2 9

  • 스레드는 프로세스 내에서 각각 Stack만 따로 할당받고 Code, Data, Heap 영역은 공유한다.
    • 각각의 스레드는 별도의 레지스터와 스택을 갖고 있지만, 힙 메모리는 서로 읽고 쓸 수 있다.
  • 같은 프로세스의 스레드들 모두 해당 프로세스의 메모리를 공유한다.
    • 프로세스 내의 주소 공간이나 자원들(힙 공간 등)을 공유한다.
    • 같은 메모리이기 때문에, 스레드 간의 통신이 빠르다.
  • 한 스레드가 프로세스 자원을 변경하면, 다른 이웃 스레드(sibling thread)도 그 변경 결과를 즉시 볼 수 있다.

자바 스레드(Java thread)

  • 자바에는 프로세스가 존재하지 않고 스레드만 존재한다.9
  • 자바 스레드는 JVM에 의해 스케줄 되는 실행 단위 코드 블록이다.
  • 일반 스레드와 거의 차이가 없으며, JVM이 운영체제의 역할을 한다.
    • 자바에서 스레드 스케줄링은 전적으로 JVM에 의해 이루어진다.
  • JVM이 스레드와 관련된 많은 정보를 관리한다
    • 관리하는 정보: 존재하는 스레드 개수, 스레드 상태, 스레드 우선순위, 스레드로 실행되는 프로그램 코드의 메모리 위치
  • 개발자는 자바 스레드로 작동할 스레드 코드를 작성하고, 스레드 코드가 실행을 시작하도록 JVM에 요청하는 일을 한다.

멀티 프로세스와 멀티 스레드의 차이

멀티 프로세스(Multi Process)

하나의 응용프로그램을 여러 개의 프로세스로 구성하여 각 프로세스가 하나의 작업(태스크)을 처리하도록 하는 것

장점 (+)

  • 자식 프로세스 중 하나에게 문제가 발생하면 그 자식 프로세스만 죽는 것 이상으로 다른 영향을 끼치지 않는다.

단점 (-)

  • Context Switching으로 인한 오버헤드
    • Context Switching: CPU에서 여러 프로세스를 돌아가면서 작업을 처리하는 데 이 과정이다. 동작 중인 프로세스가 대기하면서 해당 프로세스의 상태(Context)를 보관하고, 대기하고 있던 다음 순서의 프로세스가 동작하면서 이전에 보관했던 프로세스의 상태를 복구하는 작업을 말한다.
    • Context Switching 과정에서 캐쉬 메모리 초기화 등 무거운 작업이 진행되고 많은 시간이 소모되는 등의 오버헤드가 발생한다.
    • 프로세스는 각각 독립된 메모리 영역을 할당받았기 때문에 프로세스 사이에서 공유하는 메모리가 없어, Context Switching이 발생하면 캐쉬에 있는 모든 데이터를 모두 리셋하고 다시 캐쉬 정보를 불러와야 한다.
  • 프로세스 사이의 복잡한 통신 기법(IPC)
    • 프로세스는 각각 독립된 메모리 영역을 할당받았기 때문에 하나의 프로그램에 속하는 프로세스들 사이의 변수를 공유할 수 없다.

멀티 스레드(Multi Thread, 다중 쓰레드)

하나의 응용프로그램을 2개 이상의 스레드로 구성하고 각 스레드가 하나의 작업을 처리하도록 하는 것
하나의 프로세스를 다수의 실행 단위로 구분하여 자원을 공유하고, 자원의 생성과 관리의 중복성을 최소화하여 수행 능력을 향상시키는 것

  • 윈도우, 리눅스 등 많은 운영체제가 멀티 프로세싱을 지원하고 있지만 멀티 스레딩을 기본으로 하고 있다.
    • 한 프로세스 안에서 여러 스레드를 수행하다가 다른 프로세스로 넘어가서 그 프로세스의 스레드를 수행한다.
    • 현대 운영체제의 context switching 단위는 프로세스가 아닌 쓰레드 단위다.
  • 예) 웹 서버, 웹 브라우저(화면을 출력하는 쓰레드, 데이터를 읽어오는 쓰레드 따로 수행), Word processor, Media player
  • 각각의 스레드가 독립적인 작업을 수행해야 하기 때문에, 각자의 스택과 PC 레지스터 값을 갖고 있다.
    • 스택: 함수 호출 시 전달되는 인자, 되돌아갈 주소값 및 함수 내에서 선언하는 변수 등을 저장하기 위해 사용되는 메모리 공간
    • 독립적인 스택 메모리 공간이란, 독립적인 함수 호출이 가능하다는 말. 독립적인 실행 흐름이 추가됌

    • PC 값은 스레드가 명령어의 어디까지 수행하였는지를 알려준다. 이 값을 기억해야 하는 이유는, 명령어가 연속적으로 수행되지 않을 수 있기 때문이다 (스레드가 CPU를 할당받았다가 스케줄러에 의해 다시 선점당할 수 있기 때문이다).
  • 한 프로그램에 있는 여러 스레드는 빠른 시간 간격으로 스위칭 된다. 사용자 입장에서는 여러 스레드가 동시에 실행되는 것처럼 보인다. 5
    • concurrent: 하나의 CPU 환경에서 여러 스레드가 스위칭에 의해 동시에 수행되는 것
    • simultaneous: 여러 CPU 환경에서 여러 스레드가 실제로 동시에 수행되는 것

장점 (+)

  • 메모리 공간 등 시스템 자원 소모 감소 (자원의 효율성 증대)
    • 프로세스를 생성하여 자원을 할당하는 시스템 콜이 줄어들어 자원을 효율적으로 관리할 수 있다.
    • 스레드 간 통신에 별도의 자원이 아닌 전역 변수의 공간 또는 동적으로 할당된 공간인 Heap영역을 이용하여 데이터를 주고 받는다.
  • 시스템 처리량 증가 (처리 비용 감소)
    • 스레드 간 데이터를 주고받는 것이 간단해지고 시스템 자원 소모가 줄어들게 된다.
    • 스레드 사이의 작업량이 적어 Context Switching이 빠르다.
  • 간단한 통신 방법으로 인한 프로그램 응답 시간 단축
    • 스레드는 프로세스 내의 Stack 영역을 제외한 모든 메모리를 공유하기 때문에 통신의 부담이 적다.

단점 (-)

  • 주의 깊은 설계가 필요하다.
  • 디버깅이 까다롭다.
  • 단일 프로세스 시스템의 경우 효과를 기대하기 어렵다.
  • 다른 프로세스에서 스레드를 제어할 수 없다. (즉, 프로세스 밖에서 스레드 각각을 제어할 수 없다)
  • 자원 공유의 문제가 발생한다. (동기화 문제)
  • 하나의 스레드에 문제가 발생하면 전체 프로세스가 영향을 받는다.

멀티 프로세스 대신 멀티 스레드를 사용하는 이유

프로그램을 여러 개 키는 것보다 하나의 프로그램 안에서 여러 작업을 해결하는 것

  • 자원의 효율성 증대
    • 프로세스를 생성하여 자원을 할당하는 시스템 콜이 줄어들어 자원을 효율적으로 관리할 수 있다.
    • 프로세스 간의 Context Switching시 단순히 CPU 레지스터 교체뿐만 아니라 RAM과 CPU 사이의 캐쉬 메모리에 대한 데이터까지 초기화되므로 오버헤드가 크기 때문이다
    • 독립적인 프로세스와 달리 스레드는 프로세스 내의 메모리를 공유하기 때문에 스레드 간 데이터를 주고받는 것이 간단해지고 시스템 자원 소모가 줄어들게 된다.
  • 처리 비용 감소 및 응답 시간 단축
    • IPC보다 스레드 간의 통신 비용이 적다.
    • 스레드는 Stack 영역을 제외한 모든 메모리를 공유한다.
    • Context Switching시 스레드는 Stack 영역만 처리한다
    • 프로세스 간의 전환 속도보다 스레드 간의 전환 속도가 빠르다.
  • 다만, 동기화 문제, 스레드 간의 자원 공유로 인한 충돌 (데이터 세그먼트 내 전역변수)등의 문제가 일어날 수 있기 때문에 주의해서 써야 된다 .

References

Leave a comment