운영체제

프로세스와 쓰레드

옴악핫세 2023. 5. 5. 09:32

프로세스

운영체제로부터 자원을 할당받는 작업의 단위  → 실행 중인 프로그램

예를들어 우리가 Java 프로그램을 실행시키면 이 프로그램은 프로세스라는 이름으로 운영체제 위에서 실행됨

프로세스 구조

OS가 프로그램 실행을 위한 프로세스를 할당해줄때 프로세스안에 프로그램 Code와 Data 그리고 메모리 영역 (Stack, Heap)을 함께 할당해줌

1. Code : Java Main 메소드와 클래스 같은 코드

2. Data : 프로그램이 실행중 데이터를 저장할 수 있는 저장공간
 → 전역 변수, 정적 변수 (Static), 배열 등 초기화된 데이터를 저장하는 공간

 3.  Memory (메모리 영역)

      3-1. Stack : 지역변수, 매개변수 리턴 변수를 저장하는 공간

      3-2. Heap : 프로그램이 동적으로 필요한 변수를 저장하는 공간 (new(), mallock())

각 프로그램은 프로세스를 통해 Code, Data, Memory (Stack, Heap)를 OS로 부터 할당받음

 

프로세스의 생명주기

프로세스는 신규 (new), 준비(Ready), 수행(Running), 대기(Waiting), 종료 (terminated) 5가지 상태로 구분됨

처음 프로세스는 Ready Queue에 들어가게 되며

실행이 되고 난 후 I/O, Timeout, Event에 의해 인터럽트가 발생할 수 있음

끝나는 프로세스는 메모리 리소스를 반납하고 종료하게 됨

 

- 신규 (New)

프로세스가 이제 막 메인메모리에 올라온 상태

아직 실행하는 것은 불가능, 수용 동작을 거쳐야 준비 단계로 넘어감

 

- 준비 (Ready)

변수 초기화 등 기초 준비작업을 모두 끝나고 실행을 할 수 있는 상태

스케쥴러를 통해 발송 (dispatch)되어야 수행 상태가 됨

신규 프로세스가 수용되거나, 대기 프로세스의 I/O Event가 완료됨, 수행 프로세스가 중단됨

 

- 수행 (Running)

CPU가 실제로 프로세스를 수행하고 있는 상태

선점 스케쥴링에 의해 중단되면 준비 상태로 (CPU의 과부하가 판단되는 경우),

I/O or Event가 필요하면 대기 상태로

수행이 완료되면 종료 상태가 됨

준비 프로세스가 스케쥴러를 통해 발송되며 수행상태로

 

- 대기 (Waiting)

프로세스 도중에 I/O 작업이 필요하여 I/O 작업을 수행하는 상태

이떄 CPU는 I/O를 기다리며, 다른 프로세스를 수행

대기 상태가 끝나면 프로세스는 다시 준비 상태가 되고, 잠시 후 다시 수행 상태가 됨

 

- 종료 (Terminated)

최종적으로 프로세스가 종료된 상태

사용하던 메모리 영역이 해제됨

 

Waiting Queue

1) Job Queue : HDD에 있던 프로그램들이 메모리에 올라올 때, 만약 메인 메모리가 가득 찼거나 CPU가 다른 작업을 수행 중이라면 메모리에 올라오기 전에 어느정도 기다려야하는데 HDD의 프로그램들이 잠시 기다리는 곳을 Job Queue라고 한다.

 

2) Ready Queue : 메인메모리에 프로그램이 올라왔다고 하더라도 바로 CPU의 서비스를 받을 수 있는 것은 아니다. 다른 프로그램이 수행 중이면 기다렸다가, 해당 프로그램이 I/O를 시작하거나, 시공유시스템의 경우 기존 프로세스가 시간초과되면 실행된다. 이렇게 이미 메모리에 올라온 프로세스들이 실행을 위해 대기하는 곳을 Ready Queue라고 한다.

 

3) Device Queue : I/O장치 (e.g. 프린터, 키보드, 마우스 등)을 이용하려면 기존 I/O 작업이 끝나기를 기다렸다가 밀려있던 모든 작업이 끝나면 비로소 I/O장치를 사용할 수 있다. 프린터는 프린터큐, 마우스는 마우스큐, 키보드는 키보드큐와 같이 각각 I/O 장치들은 각자의 대기 큐를 가지고 있는데, 이러한 I/O 장치들의 큐들을 통틀어서 Device Queue라고 부른다.

 

+) 그럼 Terminated는? 이라는 질문이 나올 수 있다. 어떠한 프로세스가 종료될 때는 기다릴 필요 없이 바로 종료된다. 즉 Terminated 상태를 위한 큐는 필요 없다.

 

스케줄링 (Scheduling)

 

1) Job Scheduler : Job Queue의 프로그램들을 어떤 순서로 메모리에 올릴 것인지 결정한다. 이러한 과정은 프로그램이 새로 시작될 때, 메인메모리가 가득찬 경우 등의 상황에만 발생하므로 자주 일어나지 않고 어쩌다 한번(수분 ~ 수십분) 일어난다. 때문에 이러한 스케줄러를 Long Term Scheduler라고도 한다.

 

2) CPU Scheduler : Ready Queue의 프로세스들을 어떤 순서로 서비스 할 것인지에 대한 스케줄러이다. 시공유 시스템의 경우 이러한 과정은 1초에도 수십번에서 많게는 수백번도 일어나기 때문에 이러한 스케줄러를 Short Term Scheduler라고도 한다. 모든 스케줄링 중에서 CPU 스케줄링이 가장 중요하다.

 

3) Device Scheduler : Device Queue의 프로세스들을 어떤 순서로 I/O 장치를 이용하게 할 것인지에 대한 스케줄러이다. 이는 Disk Scheduler, Printer Scheduler, Mouse Scheduler 등 I/O, 보조기억 장치 스케줄러를 통틀어 가리키는 말이다.

 

4) Degree of Multi Programminig : 메인 메모리에 프로세스가 몇개나 올라와 있는지를 의미함. (만약 3개의 프로세스가 실행중이라면 Degree는 3)

 

5) I/O Bound Process VS CPU Bound Process : I/O Bound Process의경우 대부분의 시간을 I/O하는데 쓰는 프로세스들을 의미하고 CPU Bound Process는 대부분의 시간을 CPU로 연산하는데 쓰는 프로세스를 의미한다. 운영체제(Job Scheduler)는 이들을 적절하게 배합하여 I/O 장치와 CPU 모두 너무 오랫동안 쉬게하지 않아야한다.

 

 

주-보조 교환 (Swapping)

1) Swapping : 서버와 같이 여러 사용자가 하나의 메모리를 공유하는 경우에 만약 한 사용자가 자리를 비우면 그 사용자가 돌아올 때 까지 해당 프로세스에 메모리를 할당할 이유가 없다. 때문에 PCB(Process Control Block)의 CPU Time등을 확인해서 오랫동안 동작이 없는 프로세스는 잠시 HDD로 내려놓고, 다른 프로세스를 실행하거나 기존 프로세스에 메모리를 더 할당하는 등 메모리를 더 효율적으로 활용하다가, 해당 사용자가 돌아와서 작업을 수행하면 다시 메모리에 프로세스를 올린다. 메모리에서 HDD로 내리는 작업을 Swap Out이라고 하고, HDD에서 다시 메모리로 올리는 작업을 Swap In이라고 하며, 이러한 목적으로 사용되는 HDD 공간을 Backing Store 혹은 Swap Device라고한다.

 

2) MIdium Term Scheduler : Swapping 역시 여러 프로세스들이 HDD로 내려가고 다시 메모리로 올라오고 하기 때문에 어떤 순서로 프로세스를 먼저 내리고 올릴지 결정해야한다. 이러한 스케줄링 작업은 Short Term Scheduling 보다는 적게 일어나지만 Long Term Scheduling 보다는 자주 일어난다. 때문에 이러한 스케줄링 작업(Swapping Scheduling)을 Midium Term Scheduling이라고 한다.

 

 

문맥 교환 (Context Switching)

1) Context Switching : 시공유 시스템의 경우 일정 시간이 지나면 기존 프로세스를 Ready 상태로 만들고 다른 프로세스를 Running 상태로 만들어서 실행한다. 이렇게 실행하는 프로세스를 Switch 하는 것을 통틀어서 Context Switching 이라고 한다.

 

2) Scheduler : Context Switching을 전문적으로 담당하는 스케줄러는 위에서 배운 CPU 스케줄러이다. CPU 스케줄러는 Ready Queue에 대기 중인 프로세스를 어떤 순서로 실행시킬 것인지에 대한 스케줄러이다.

 

3) Dispatcher : 만일 프로세스 A의 코드 중 100번 라인까지 실행했고 작업 중에 10개의 데이터를 레지스터에 저장했었다면, 스위치할 때 이 정보들을 보존해야 A의 차례가 돌아왔을 때 이전에 수행하던 작업이 끊기지 않고 수행될 수 있다. 때문에 프로세스 A를 수행하다가 B로 넘어가면 그러한 정보를 저장하고, 다시 A의 차례가 왔을 때, 정보를 다시 꺼내서 PC, SP, Register 등에 할당한다. 이러한 작업을 수행하는 프로그램을 Dispatcher라고 한다.

 

❓ 대부분의 OS는 CPU 스케쥴링 방법 중 시간공유 시스템을 사용할까요?

  • 네, 대부분의 운영체제는 CPU 시간을 여러 프로세스나 스레드에 공평하게 분배하는 CPU 시간 공유 시스템을 사용합니다.
  • CPU 시간을 효율적으로 사용하기 위해서, 운영체제는 CPU를 사용하지 않는 프로세스나 스레드가 있다면 다른 프로세스나 스레드에게 CPU 시간을 할당합니다.
  • CPU 시간 공유 시스템을 사용함으로써, 여러 프로세스나 스레드가 동시에 실행되는 것처럼 보일 수 있습니다.
  • 그러나 실제로는 CPU가 매우 빠르기 때문에 매우 짧은 시간에 여러 프로세스나 스레드를 번갈아가며 실행할 수 있습니다.
  • 이를 통해 CPU가 최대한 효율적으로 사용될 수 있으며, 운영체제는 더 많은 프로세스나 스레드를 동시에 실행할 수 있습니다. </aside>

 

 

쓰레드

프로세스가 할당받은 자원을 이용하는 실행의 단위, 즉 쓰레드는 프로세스내에서 일하는 일꾼(코드실행의 흐름)

쓰레드의 생성

프로세스가 작업중인 프로그램에서 실행 요청이 들어오면 쓰레드 (일꾼)을 만들어 명령을 처리하도록 함

 

쓰레드의 자원

프로세스 안에는 여러 쓰레드 (일꾼)들이 있고, 쓰레드들은 실행을 위한 프로세스 내 주소공간이나 메모리공간 (Heap)을 공유받음

추가로, 쓰레드 들은 각각 명령처리를 위한 자신만의 메모리 공간 (Stack)도 할당 받음

 

Java 쓰레드

일반 쓰레드와 동일하며 JVM 프로세스 안에서 실행되는 쓰레드를 지칭함

 

Java 프로그램을 실행하면 앞서 배운  JVM 프로세스 위에서 실행됨

Java 프로그램 쓰레드는 Java Main 쓰레드부터 실행되며 JVM에 의해 실행됨

 

 

 

 

 

 

멀티 쓰레드

Java는 메인 쓰레드가 main() 메서드를 실행시키면서 시작됨

메인 쓰레드는 필요에 따라서 작업 쓰레드를을 생성해서 병렬로 코드를 실행 시킬 수 있음

Java는 멀티 쓰레드를 지원함

 

  • 장점
    1. 병렬 연산으로 인한 성능향상
       여러개의 쓰레드 (실행 흐름)을 통해 여러개의 작업을 동시에 할 수 있어서 성능이 좋아짐
    2. 효율적인 메모리 관리
       스택을 제외한 모든 영역에서 메모리를 공유하기 때문에 자원을 보다 효율적으로 사용할 수 있음
    3. 비동기
      응답 쓰레드와 작업 쓰레드를 분리하여 빠르게 응답을 줄 수 있음
  • 단점
    1. 동기화 문제
      프로세스의 자원을 공유하면서 작업을 처리하기 때문에 자원을 서로 사용하려고 하는 충돌이 발생하는 경우를 의미
    2. 교착 상태 (데드락)
      → 둘 이상의 쓰레드가 서로의 자원을 원하는 상태가 되었을 때, 서로 작업이 종료되기만을 기다리며 작업을 더 이상 진행하지 못하게 되는 상태를 의미

 

시장에서 프로그래머가 해결해야 하는 문제는 계속 변화함

문제가 변화하기 때문에, 프로그래밍 언어에 요구되는 기능들도 변화함

 

 

 

 

각 프로세스는 독립적인