본문 바로가기
ComputerScience/OperatingSystem

[OS] 1. 운영체제, 프로세스(Process), 쓰레드(Thread)

by Develaniper 2021. 5. 17.

※본 포스팅은 공부목적(https://develaniper-devpage.tistory.com/77)에 따라 해당 블로그와 깃허브를 참조하여 제작된 포스팅 입니다.

1. 운영체제

 운영체는 시스템의 자원과 동작을 관리하는 소프트웨어입니다. 운영체제는 다음과 같은 일을 합니다.

 1. 프로세스 관리, 2. 저장장치 관리, 3. 네트워킹, 4. 사용자 관리, 5. 디바이스 드라이버

이  다섯가지 일들에 대해서 차근차근 공부해 봅시다!!

 

2. 프로세스 & 쓰레드

1) 프로세스(Process), 쓰레드(Thread)란?

 - 프로세스 :  메모리 상에서 실행중인 프로그램(작업)

 - 쓰레드 : 프로세스 안에서 실행되는 여러 흐름의 단위

 

그냥 당연하다고 생각하던 프로세스가 여기서 확인 할 수 있습니다. 이건 테크톡이라는 유튜브에서 프로세스 & 쓰레드에 대해서 발표할 때 말해주셔서 '아.. 그러네'라고 생각한 건데요.. 이렇게 실생활(?)에 연관지으면 더 기억이 잘 날것 같네요.

 

쓰레드 확인 법은 다음과 같습니다.

 

작업관리자 세부정보-> 맨 위정렬 탭 마우스 우클릭-> 열선택

 

 

아래로 내리다가 쓰레드를 선택합니다.

프로세스별로 몇개의 쓰레드를 사용하고 있는지 확인 할 수 있네요

 

 

2) 프로세스 & 쓰레드 구조

위는 프로세스의 구조를 나타낸 도식입니다. Process는 최소 하나의 쓰레드를 가지고 있으며 단 하나의 Code, Data, Heap영역을 가지고 있습니다. 또한, 한 프로세스는 여러개의 쓰레드를 가지고 있습니다.

 

이 점에서 생각할 수 있는 점은 같은 프로세스 내에있는 쓰레드는 같은 Code, Data, Heap공간을 공유하고 Stack공간만 따로 사용합니다. 하지만 공간을 공유하는 것에서 생길 수 있는 문제는 동기화 문제입니다. 각각 사용 시점이 어긎남에 따라 일관성이 떨어질 염려가 있습니다. 이와 관련해서는 뮤텍스, 세마포어등의 개념이 있는데 이건 차후에 정리하겠습니다.(아직 세마포어랑 뮤텍스는 알듯 말듯.....)

 

각각의 요소에 대해서 알아보면

 

- Code : 코드 자체를 구성하는 메모리 영역

- Data : 전역변수, 정적변수, 배열 등

- Heap : 동적 할당 시 사용(new(), mallock() 등)

- Stack : 지역변수, 매개변수, 리턴값(임시 메모리 영역)

 

자바의 객체지향에 대한 포스트를 쓰면서 이와 관련해서 다룬적이 있는데요. JVM자체가 하나의 가상 머신(컴퓨터)이기 때문에 OS역할을 한다고 보면 될 것 같습니다. JVM에서는 메서드영역, Heap영역, Stack영역(호출스택)이 있었습니다.

각각 Code, Data-메서드 영역, Heap-Heap, Stack- 호출스택 이정도로 대응 되는 것 같습니다. 자바기준으로 설명하고 왜 각 영역에 해당하는지 설명해보겠습니다.

 - 메서드 영역에는 컴파일 시 *.class파일의 클래스와 클래스 변수가 저장되니 코드자체를 구성하는 메모리 영역이라 볼 수 있을 것 같습니다.

 - Heap영역에는 모든 인스턴스를 저장하는 공간인데 객체는 동적으로 할당되고 new()를 사용하여 생성되고 영역의 이름도 같습니다.

 - Stack영역 또한 호출스택으로 이름이 같고 메서드가 실행될 동안 지역변수와 리턴 값등이 임시로 저장되는 영역이기 때문에 같은 공간입니다.

 마지막으로 Data영역이 없는데 클래스 변수를 정적변수, 전역변수라고 볼 수 있기 때문에 Data영역도 메서드 영역에 포함될 것 같습니다.

 

 

 두 작업단위에 대해 알아봤으니 장, 단점도 알아봐야겠죠?

3) 프로세스 vs 쓰레드 (멀티프로세싱, 멀티쓰레딩에서의)

 

- 멀티 프로세스

멀티 프로세스는 부모 프로세스, 자식프로세스 모두다른 Code, Heap, Data, Stack을 사용하고 있습니다.

- 멀티 쓰레드

반면에 쓰레드는 Stack만 따로 사용하며 같은 Code, Heap, Data영역을 사용하고 있습니다. 더 정확하게는 Process안에 Thread가 있는 것이 맞겠네요.

 

- 프로세스 장점

  • 하나의 프로세스가 죽더라도 다른 프로세스에는 영향을 끼치지 않고 정상적으로 수행될 수 있습니다.
  • 안전성(메모리 침범 문제를 OS가 해결)

- 프로세스 단점

  • 프로세스간 자료 공유(통신)방법이 쓰레드에 비해 복잡하다
  • 각 독립된 메모리 영역을 가지고 있어 작업량이 많을 수록 오버헤드 발생(ContextSwitching으로 인한 성능저하)

- 쓰레드 장점

  • 응답성 증가 : 프로그램의 일부분(스레드)이 중단되거나 긴 작업을 수행하더라도 프로그램의 수행이 계속되어 사용자에 응답성이 증가한다.
  • 경제성 증가 : 프로세스 내의 자원을 공유하여 메모리와 시스템 자원을 경제적으로 사용할 수 있다.
  • 쓰레드 사이의 작업량이 상대적으로 작아 Context Switching이 빠릅니다.(시스템 처리량 증가-처리비용 감소)
  • 독립적인 프로세스에 비해 공유 메모리만큼의 시간, 자원 손실이 감소하여 전역변수와 정적변수에 대해 공유 가능

- 쓰레드 단점

  • 오류로 인해 하나의 스레드가 종료되면 전체 스레드가 종료될 수 있다.
  • 동기화 작업(뮤텍스, 세마포어)을 통해 스레드의 처리순서와 공유자원에 대한 처리를 할 때 병목현상을 발생시켜 성능이 저하 될 수 있다.
  • Context Switching, 동기화 등의 이유 때문에 싱글 코어 멀티 쓰레딩은 쓰레드 생성 시간이 오래걸려 오히려 오버헤드로 작용할 수 있다.
  • 안전성 문제. 하나의스레드가 데이터 공간을 망가뜨리면, 모든 스레드가 작동 불능 상태-> 이는 임계구역(Critical Section 기법으로 예방/해결할 수 있다.

 

 프로세스의 장점이 쓰레드의 단점으로 나오고, 쓰레드의 장점이 프로세스의 단점으로 나옵니다.

 

요약하자면 프로세스를 사용하면 오버헤드가 크다는 문제가 생기고 쓰레드를 사용하면 안전성이 떨어진다는 문제가 생깁니다.

 

즉, 프로세스를 사용하면 각각 메모리를 많이 사용하지만 공동으로 사용하는 메모리가 없으므로 안정적이라는 장점이 있지만 그만큼 중복되는 메모리가 많아서 쓰레드에 비해 공간이 낭비되고 프로세스를 교체(Context Switching)할때 걸리는 시간이 오래걸린다는 단점이 있습니다.

 

 쓰레드의 경우에는 사용하면 한 프로세스내에서 Code, Heap, Data 부분을 공유하기 때문에 더 적은 공간이 필요하지만 위에서 언급한 바와 같이 이런 문제로 인해서 각 쓰레드의 작업 시간이 겹치거나 한 프로세스가 데이터를 망쳐놓으면 모든 쓰레드에 문제가 생긴다는 것이 문제점입니다.

 

한마디로 둘의 장/단점을 정의하면 자원의 공유 여부에 따른 특징이라고 정리할 수 있을 것 같습니다.

 

 

※ 동기화 문제는 멀티 프로세스 방식 IPC의 임계구역등에서도 발생한다. 단지 여기서는 멀티 쓰레드, 프로세스를 돌릴 때 다른 쓰레드, 프로세스간에 데이터를 주고 받을 필요가 없는 경우에 프로세스, 스레드를 만들기 전에 사용하던 객체나 변수를 가지고 각 작업을 할 경우를 염두해 둔 것 같다.

 

 

3. Context Switching

 1) Context Switching이란?

 프로세스의 상태 정보를 저장하고 복원하는 일련의 과정

즉, 동작 중인 프로세스를 대기상태로 만들면서 프로세스의 상태를 보관하고, 대기중이던 다음 순번의 프로세스를 복구하는 과정을 말합니다.

2) Context Switching을 하는 이유

 만일 프로그램이 실행되는 중에 중요한 이슈가 생겨서 다른 프로그램을 실행해야 한다면 어떤 일이 진행되야할까요?

기존에 진행하던 프로그램을 강제종료하고 새 프로그램을 진행하기에는 기존의 데이터도 무척 중요할 수 있기 때문에 위험성이 높습니다.

 따라서 기존의 프로세스의 정보를 저장하고 새 프로세스를 실행해는 과정이 필요합니다. 이것을 Context Switching이라고 부르는 것입니다.

 Context Switching을 사용하는 경우는 다음과 같습니다.

  • 프로세스 종료
    • 에러, 예외, 일반적으로 프로세스가 종료되었을 때 새로운 프로세스로 Context Switch됨니다.
  • 가능한 CPU점유 시간이 만료 되었을 때
    • 대표적으로 RR(Round-Robin)같은 CPU 스케줄링에서 정해진 시간이 만료 되면
  • Blocking system calls
    • I/O 요청, 파일 오픈과 같은 시스템 콜이 발생할 경우
    • Page fault - 가상 메모리 주소가 가상 메모리에 있으므로 main memory로 가져올때(요구페이징의 경우로 차후에 다룰 예정) Page fault라는 인터럽트가 발생한다.
  • I/O 인터럽트
    • I/O가 완료되면 Block 상태의 프로세스를 Ready상태로 바꿈.

3) Context Switching이 진행되는 방법

# Task의 대부분 정보는 Register에 저장되고 PCB(Process-Controll-Block)로 관리됩니다.

  1. 현재 실행하고 있는 프로세스의 PCB 정보를 갱신합니다.(Process Stack, Ready Queue)
  2. PCB를 Queue에 옮깁니다.(Ready or Ready or ready/suspend)
  3. 다음 실행할 프로세스의 PCB 정보를 읽어 Register에 적재합니다.
  4. 메모리 관리 데이터 구조를 갱신합니다.
  5. CPU가 이전에 진행했던 과정을 연속적으로 수행을 할 수 있습니다

※스케줄링 순서에 따라 현재 실행 PCB를 저장하고 1 에서 저장한 PCB내용을 다시 불러옵니다.(프로세스가 끝날 때 까지)

 

PCB에 저장되는 정보는 다음과 같다

이를 요약하면 프로세스가 진행됨에 따라 변하는 모든 정보에 대한 저장소 역할을 한다. 프로세스 상태와 프로그램 카운터는 PCB의 핵심 요소라 할 수 있으니 꼭 알아두면 좋을 것 같습니다.(동작할 때는 나머지도 중요하겠지만..)

 

4) Process State(프로세스 상태 전이도)

PCB에 저장되는 프로세스 상태의 전이도는 다음과 같다.

 

 

위의 running과 이어진 모든 과정에서 Context Switching이 일어난다고 보면 될 것 같습니다.

running으로부터 나가는 화살표일 때도 들어오는 화살표이면 더더욱 그렇겠죠?

 

5) Context Switching 비용

Context Switching의 시간은 프로세스 실행에 있어서 순전히 오버헤드 시간입니다. 프로세스의 입장에서 보면 실행 시 전혀 필요 없는 과정이기 때문이죠. context Switching을 하는 비용은 다음과 같습니다.

  • Cache 초기화
  • Memory Mapping 초기화
  • Kernel(커널은 항상 실행됩니다.(메모리 접근시 필요))

6) 프로세스 vs Thread의 Context Switching비용

쓰레드는 Stack을 제외한 메모리를 공유하기 때문에 프로세스보다 비용이 더 적게 듭니다. 단적으로 말하면 교체할 문맥이 프로세스가 더 많죠. (프로세스 4개 vs 쓰레드 1개(Stack))

 

- 추가 참조 사이트

https://eun-jeong.tistory.com/20 (쓰레드의 장/단점)
https://velog.io/@ckstn0777/OS-스레드
https://nesoy.github.io/articles/2018-11/Context-Switching (컨텍스트 스위칭)
https://conatuseus.tistory.com/5 (컨텍스트 스위칭)
http://blog.naver.com/PostView.nhn?blogId=4717010&logNo=60207137085(프로세스 상태도)

 

'ComputerScience > OperatingSystem' 카테고리의 다른 글

[OS] 6. 가상메모리  (0) 2021.05.24
[OS] 5. 동기화(세마포, 뮤텍스)  (0) 2021.05.22
[OS] 4. 메인 메모리  (0) 2021.05.20
[OS] 3. 메모리  (0) 2021.05.20
[OS] 2. 교착상태(DeadLock)  (0) 2021.05.19

댓글