본문 바로가기

CS 이론/운영체제

[운영체제 -1] Process 와 Thread

728x90

 

(1) Process

 

홍성수 교수님 수업 때 말씀하시길, 누가 운영체제 수업 들었구나, 그럼 프로세스가 뭔지 말해봐라? 라고 질문을 한다면 다음과 같이 깔끔하게 답변할 수 있어야 한다고 한다. 

 

Process is a Program in execution

 

실행중인 프로그램을 말한다. 메모리 주소가 형성이 되어 메모리에 올라가 있는 상태가 비로소 execute 된 것이며, 교수님 말씀을 빌리면, program 은 그저 body이고, process 가 life 라고 한다. 그만큼 중요한 개념인 것 같으니 program 과 process, thread의 차이를 확실히 이해하고 가면 좋을 것 같다. 

 

 

**  참고로 그렇다면 Process와의 차이 측면에서 Program은 어떻게 정의할까? 

Program은 이미 성취하기 위한 목적(Pre-defined Task)을 달성하기 위해 컴퓨터가 수행해야 하는 Sequence of Instructions를 말한다. Process는 이런 프로그램이 수행을 위해 Memory Loading이 된 상태를 말하니, 둘의 개념은 성격상으로도 확실히 다른 것이다. 

 

 

"Program in Execution"이란 지난 포스트에서 언급했듯이, 실행(Execution)이 되었기 때문에 메모리 주소 공간(Address Space)가 할당된 상태를 말한다. 이 상태에서 Process의 동작을 이해하기 위해서는 Process의 문맥 Process의 상태를 이해해야하는데, 천천히 생각해보자. 

 

    1. Process Context (문맥)

 

Process의 내부와 실행중인 프로그램들의 주소공간

 

CPU 내부에는 Program Counter라는 친구가 있다. 이 친구는 실행중인 Process의 Code Segment에서 수행할 Instruction들을 가져와서 레지스터에게 전달한다. 이 Program Counter가 가르키고 있는 곳은 실행중인 Process의 현재 위치를 파악하기 위해서 중요한 값이다.

 

컴퓨터는 Process의 현재 상태를 알아야 하기 때문에, 실행중인 Process가 도중에 어디까지 진행이 되었는가를 정확하게 파악하며 진행을 해야 한다 (아래 "프로세스 교체"에서 중요하게 다루게 된다).

이렇게 Program Counter 값이 어디를 가르키고 있는가?  Process의 메모리에는 어떤 정보가 담겨 있는가? 해당 Instruction 에 있는 함수를 호출하면 Stack Segment에 값이 담길텐데, 어떤 함수인지? 현재 레지스터에는 어떤 값이 들어가 있는가?  등등.. 이렇게

 

 

Process의 현재 상태를 나타내기 위해 필요한 모든 요소를 Process Context 라고 한다

 

 

프로세스의 문맥에는 크게 세가지 상태가 있다. 

 

1) Hardware Context : 현재 Program Counter의 값 상태, 각종 레지스터가 가지고 있는 값 상태

2) Memory Context : 현재 Process의 메모리 공간에는 저장되어 있는 값 상태

3) System Context : 운영체제에서 관리하는 현재 Process 관련 커널 자료 구조 (ex: PCB, Kernel Stack 등)

 

 

Kernel Stack이란?

Process가 실행되다보면 System Call(지난 포스트 참고)을 하게 되고, 그렇게 되면 Program Counter는 OS Program을 가르키게 된다. Kernel 역시 프로그램이므로 Kernel 함수를 호출하면 Stack Segment에 Kernel 함수가 쌓인다. 하지만 Kernel은 여러 프로세스들이 공유하는 자원이다. 따라서 Kernel은 누가 호출했는지 알아야 하므로 위 그림처럼 Stack에 무슨 프로세스가 호출해서 쌓였는지 같이 저장을 하는데, 이를 Kernel Stack이라 한다. 즉, A Process가 실행하는 커널 함수들은 A Process의 Kernel Stack 영역에 저장되는 것이다.

 

PCB(Process Control Block)란?

PCB 공간의 모습

OS는 컴퓨터 안에서 돌아가는 프로세스들을 관리하므로, Process들이 새로 생길 때마다 자신의 Address Space 중 Data Segment에 해당 Process의 PCB를 하나 생성해서 저장해 둔다. Process 들 간에 CPU를 계속해서 주고받기 때문에 (Time-Sharing) CPU를 넘겨 받았을 때 지난번 이 Process를 어디까지 했는지 Context를 정확히 파악해야 그 이후 instructions들을 실행할 수 있기 때문에 PCB를 사용하여 다음과 같은 필요한 정보들을 저장한다.

 

(1) OS가 관리상 사용하는 정보 : Process State, PID, Priority 등

(2) Hardware 문맥 : Program Counter값, CPU에 어떤 레지스터 값들을 넣어서 실행중이였는지 등

(3) Memory 문맥 : 현 Process의 메모리 공간의 상태값 및 주소 위치 등

(4) 파일 관련 : 그 외의 정보

 

 

(Q: 의문점이 드는건.. 문맥의 종류중 System Context 에 해당하는게 PCB인데, 그럼 결국 Memory 문맥과 H/W 문맥 모두 PCB에 저장하는걸까..?)

 

 

    2. Process State (상태)

 

지금까지의 복잡한 내용들을 이해 못했다면, 다음과 같이 간단하게 정리하고 넘어가보자. 

 

"Process들은 OS가 스케줄링해준 순서에 따라 CPU를 계속 주고 받기 때문에, 이전의 Process의 현재 상황을 알고 있어야한다"

"그렇기 위해서 사용되는 모든 정보를 Process Context이라 하고, Memory/H.W/System Context 가 있다"

"System Context에 사용되는 자료구조는 Process당 생성되는 Kernel Stack과 PCB가 있다."

 

이제 Process 가 운영이 되기 위해 구분이 된 Process의 상태들에 대해 알아보자. 

 

Process State Flow

Process 는 크게 3가지 State 값을 가진다. 

 

Running - CPU를 잡고 instructions들을 실행중인 상태

Ready - CPU를 기다리는 상태 (다른 모든 준비는 되어 있어야 한다. 물리적인 메모리에 올라와 있어야 한다)

Waiting(Blocked) - Address Space의 Code Segment가 메모리가 아닌 Disk에 내려가 있는 상태 (CPU를 줘봤자 일을 못한다)

(참고로 New -> Ready가 되는 과정에서 admitted 된다고 하는데, 프로그램이 실행되어 Memory Load가 되는걸 말한다)

 

중요한 부분은 Running 상태에서 방출되는 경로들인데, 다음과 같이 방출될 수 있다. 

 

1) 일이 그냥 끝난다 (Exit)

2) IO와 같은 오래걸리는 작업을 해야하기 위해서 자진해서 CPU를 내놓는 경우 (S.W Interrupt, Synchronous Interrupt, Non-Preemptive Scheduling)

3) 나는 계속 돌고 싶은데, 어떠한 이유로 OS가 강제로 가져가는 것. CPU만 주면 다시 돌 수 있다. (H.W Interrupt, Asynchronous Interrupt, Preemptive Scheduling)

 

지난 포스트에 Interrupt와 연관지어서 설명 짓자면, 내 프로그램이 일을 하다가 IO가 수행되어야 하는 Instruction을 만나면 System Call을 하기 위해 Interrupt Lines를 작성하여 자진해서 CPU를 OS에게 준다고 하였고, 이를 S/W Interrupt, Synchronous Interrupt라고 하였다. 이렇게 되면 해당 Process는 자진해서 CPU를 반납하게 되고, IO입출력을 기다리는 Waiting State로 바뀐다.

그 후 CPU는 다음 Processing을 하다가, IO가 끝나면 Device Controller에서 Interrupt Lines를 작성한다고 했고, CPU는 이를 확인하고 OS에게 CPU가 넘어가게 된다. 여기서 진행중이던 "다음 Process" 입장에서는, CPU만 주면 계속 할 수 있는데 강제로 CPU를 빼앗기게 된 부분을 알아야 한다. 이렇게 Device Controller, 혹은 Timer 등의 요인으로 인해 발생하는 Interrupt 를 H/W Interrupt, Asynchronous Interrupt 라고 하고, 이 Process는 바로 Ready State로 바뀌게 된다.

 

 

State 값은 PCB의 OS관리 정보 측면에 저장된다고 위에서 언급하였다. 그렇다면 이 모든 Process들의 State을 매번 확인할 수도 없을 거고, 가장 중요한 CPU 할당 순서를 알아야 하는데, 그 Scheduling 정보는 어디에 저장을 하는 것일까? (Scheduling된 대로 OS가 CPU를 분배하지만, 지금 단계에서 Scheduling은 FIFO로 가정한다)

 

 

Process State Queue와 Flow 모습

 

위 그림과 같이 Process 의 상태에 따라 Queue 들이 분포되어 있는 것을 알 수 있다. 우선 CPU 안에는 반드시 하나의 Process 가 Running State 으로 자리 잡고 있다. 이 때 CPU를 기다리는 Process 들은 Ready Queue에 FIFO (기본적으로)에 따라 배열이 되어 있다. OS가 CPU를 다음에 누구한테 넘겨줄지 Scheduling 을 하여 이 Ready Queue 에서 가져오는 것이라고 보면 된다. 

 

(Q: 실제로는 FIFO가 아닌 상태로 Scheduling을 계속 계속 하는걸로 아는데, 그러면 QUEUE가 아니지 않나..?? QUEUE에 Process가 있다는 것은 무슨 뜻일까??) 

 

만약 System Call에 의해 CPU를 OS에게 반납 하게 되면 해당 프로세스는 위 그림처럼 해당 IO Device Queue 에 가서 기다리게 된다. 이후 지난 포스트에서 구체적으로 배웠듯이 IO가 끝나면 H/W Interrupt 가 발생하게 되고, 현재 CPU를 점유중이던 Process는 CPU를 뺏겨 Preemptive Scheduling 이 발생하게 된다. 그러면 OS 가 IO 작업 완료 여부를 확인 후, Scheduling을 실시하여 CPU를 뺏긴 Process 에게 다시 돌려주거나 (일반적), 다른 우선 Process 들에게 CPU를 할당하게 된다.  그리고 IO 작업을 진행하며 Waiting State 였던 Process는 다시 Ready State 가 되어 Ready Queue에서 기다리게 된다.

 

참고로 Waiting State 는 꼭 H/W IO 자원에 대해서만 일어나는 건 아니다. 위 그림처럼 Shared Resources (공유 데이터)에 여러 프로세스가 동시에 접근할시 Resources Queue 라는 자료구조도 있어서 대기할 수 있도록 되어 있다. 여러 프로세스가 공유 데이터에 동시에 접근하면 일관성이 깨지기 때문이다. 참고로 이 이야기는 나중에 열쇠와 관리인 이야기로 구체적으로 다룰 것이다.

 

어떻게 돌아가는지 논리에 대해 알았으면, 항상 "실제로" 어떻게 돌아가는지 아는 것이 중요한 것 같다. 이 Queue 들에는 실제 뭐가 저장되는거고, 어디에 있는걸까? Queue 관리는 모두 운영체제가 하는 일이라고 생각하면 된다. 그렇다면 당연히 운영체제가 관리하는 자원에 있을테니, 운영체제 (kernel)의 주소 공간 중 Data Segment 에 자료구조들을 만들어 놓고 관리하고 있다. 즉, 그림상 저렇게 그려놓은거지, 다 운영체제 Data Segment 안에 있는 자료들이다. (Q: IO Queue 들도 다 그럴까??)

또한, 위에서 잠깐 언급했던 PCB들을 줄 세워 놓게 된다. 참고로, PCB는 Process Control Block 으로, Process 의 문맥을 관리하기 위해 커널의 Data Segment 에 프로세스별로 저장해두는 메모리 공간이다. 말그대로, Block Memory 이지, 객체 단위? 같은게 아닌 것 같다. Memory Block 이란 (위키피디아 상..) 운영 체제 또는 프로그램이 기억공간을 임의적으로 분할하여 사용하는 하나의 단위를 말한다. 즉, 그냥 공간을 실제로 마련하고, 거기에 저장하고, 그 묶음을 Block 이라고 부르는 것이다.블록의 크기가 일정한 것을 페이지, 그렇지 않은 것을 세그먼트라고 한다. 왜 다 Segment 라 부르는지 이제 이해가 된다. (결국 다 메모리 블럭이였던 것) 

 

프로세스가 어떤식으로 관리가 되는지, 관리가 되기 위해 어떤 것들이 어떤 방식으로 상호작용을 하는지 어느정도 이해한 것 같다. 그렇다면 앞에서 말했던 Process Context 가 존재하는 이유, Context Switching 에 대해서 한번 이해해보자. 

 

 

    3. Context Switch (문맥 교환)

 

Time Sharing 운영체제에서는 많은 프로세스들끼리 Interrupt로 인해 지속적으로 CPU를 줬다가 뺏기면서 OS가 운영이 된다고 해도 과언이 아닐 정도라고 했다. Interrupt를 당해서 CPU를 뺏겼다가 다시 CPU를 받는다는 것은, 이전에 실행되던 부분부터 다시 실행을 한다는 의미이다. 따라서 CPU를 넘길 때, 현재 Process Context를 저장하고, CPU를 받는 Process 의 이전 Context를 불러오는 (처음이라면 Context 준비) 과정이 필요한데, 이를 Context Switch (문맥 교환) 이라고 한다. (CPU가 넘어가는 과정)

 

문맥교환이 발생하여 Process A를 저장하고 B를 불러오는 모습

Process A 가 실행이 되던 중에 Interrupt 가 발생해서 Process B 가 실행이 되어야 하는 상황이라고 가정해보자. 일단 CPU 제어권은 운영체제에게 넘어간 상황이고, 운영체제는 A의 PCB에 현재 CPU 레지스터에 저장되어 있던 값들 (Program Counter, Memory Map 등)을 저장한다. PCB에 저장하는 것이므로 OS의 Data Segment 안에 저장되어 있는 것임을 확인할 수 있다. 그 다음 Process B도 재개되는 Process일 것이다. 따라서 B의 PCB에서 이전에 저장되었던 값들을 찾고 각 H/W 장치들에 다시 값을 주입한 다음에 진행시키는 과정이 간단하게 Context Switch가 일어나는 과정이라고 볼 수 있겠다.

 

여기까지만 이해하고 넘어가도 충분하다. 실제로 일어나는 문맥교환은 아주 훨씬 더 복잡하기 때문이다. 하지만 내부적으로 일어나는 과정을 아주 조금만 더 구체적으로 살펴보자.

 

Context Switch 중 PCB에  Register 값들이 저장되는 Stack의 모습

해당 그림을 보면 못보던 친구들이 등장하는데, 그 의미는 다음과 같다. 

OS PCB Current : OS 내부의 Global 변수로, 현재 실행중인 Process 의 PCB가 저장되어 있는 주소를 가르킨다. 

Stack Pointer (SP) : 위에서 말한 Program Counter와 헷갈리기 쉬운 개념이다 (둘다 레지스터). SP란 Program Stack의 시작 지점을 가르키는 레지스터이다. (Program Counter 는 다음 Instruction 을 가르킨다) 

 

Interrupt가 발생하면, OS는 Interrupt Vector를 통해 무슨 Interrupt인지 확인하고, ISR을 통해서 수행시킨다. ISR은 Context Swtich가 실행될 시 현재 CPU에 저장되어 있는 PC, SP와 모든 문맥들을 PCB Stack에 Push Operation 을 통해서 쌓아둔다. 그리고 Scheduler를 호출하여 다음 CPU를 줄 Process 를 선정하고, OS PCB Current 를 그 Process를 가르키도록 변경하게 된다. 보통 이 Process도 Stack에 이전에 저장된 값들이 Stack에 쌓여있을 것이기 때문에, Stack Pointer가 가르키는 시점부터 (시작지점) Pop Operation을 수행하여 CPU 레지스터들에 값들을 다시 저장시키게 된다. 그리고 Program Counter가 가르키는 instruction 부터 수행을 재개하게 되며, 이것이 Context Switching 되는 과정이다.

 

사실 Interrupt (Sys.Call 혹은 HW Interrupt) 가 발생한다고 해서 문맥 교환이 꼭 발생하는 건 아니다. 즉, Kernel Mode 로 들어간다 = 문맥교환이란 뜻이 절대 아니다. 왜냐하면 CPU가 이전에 수행중이던 Process에게 다시 반환될 수 있기 때문이다. 물론 이 경우에도 어쨌든 CPU가 OS에게 넘어가면서 레지스터 값들이 변경되어야 하기 때문에 어느정도 Context Saving 은 필요하다. 하지만 Process 자체가 교체되는 것에 비해서는 Overhead가 훨씬 적기 때문에, 두 과정은 다르다고 보면 될 것 같다. (ex: Process의 Cache Memory는 Context Switch 시 모두 지우게 되지만, CPU를 바로 돌려받는 경우 유지를 시킨다)

 

 

    3. Process Scheduler

 

 

OS가 운영되면서 가장 중요한 것 중 하나는 Scheduling 을 수행한다는 점이다. 구체적인 Scheduling 방식은 나중에 자세히 얘기하게 되겠지만, Process를 관리하기 위해서 OS가 어떤 Scheduler 들을 두고 있는지 잠시 살펴보자. 

 

1> Short-Term Scheduler (CPU Scheduler) 

우리가 흔히 생각하는 스케줄러이다. OS에서 다음에 어떤 Process에 CPU를 줄지 결정하는 문제로, 짧은 단위로 스케줄링이 일어나게 된다. 

 

2> Long-Term Scheduler (Memory Scheduler, Job Scheduler)

위에서 배웠던 Process State에서 Ready State 이 되기 전에 New State 이라는 과정을 거친다. Process 가 생성이 되고, 메모리에 로딩이 되고서야 Ready State가 되는데, 이처럼 메모리 주소 공간이 형성되어 new > ready state 로 넘어오는 과정을 admitted 과정이라고 부른다. 이 때, 시작되는 Process들 중 어떤 것들을 Memory에 올려서 Ready Queue 에 PCB를 대기시킬지 결정하는 Scheduler를 Long-term Scheduler라고 부른다. 즉, 메모리를 어떤거에 주냐에 대한 문제를 다룬다.

위에 쓴 말이 이해가 안되고 뭔가 이상하다고 느껴진다면 정상이다. 왜냐하면 Process를 실행시키면 일단 메모리에 강제로 올라가는 것은 맞기 때문이다 (이건 우리가 그런 Time-Shared OS를 쓰기 때문인데, 이 문제는 이제 다룰 것이다)

일단은 그냥 단순하게 Memory Loading된 프로세스 들 중 유지시켜야 할 것들을 결정하는 부분을 말한다고 보면 될 것 같다. 즉, 메모리에 프로그램이 몇 개 돌아가고 있는지, Degree of Multiprogramming을 관리해주는 중요한 스케줄러이다. 

하지만 우리가 보통 사용하는 Time-Sharing OS에서는 장기 스케줄러가 없다! 즉, 방금 말했듯이 100개 실행하면 메모리에 100개 다 올라간다. 그렇다면 매우 중요한 문제인, Degree of Multiprogramming 은 어떻게 관리해줄까?

 

3> Mid-Term Scheduler (Swapper)

Time-Shared OS에서는 스와퍼를 두는데, 메모리에 너무 많이 로딩되어 있으면 디스크로 그냥 쫓아내는 역할을 한다. 즉, 프로세스에게서 메모리를 빼앗는 문제를 결정한다. Long Term 과는 비슷해 보일 수는 있으나, 하는 역할이 다르다고 생각하면 된다. Long-Term은 다시 말하지만 다 주는 것이 아니다. 누구한테 줄지를 Scheduling하여 결정한다. 하지만, Mid-Term 은 Time-Shared OS에서 채택되는 방식으로, 100% 다 메모리 공간을 내어주지만, 누구의 공간을 뺏을지를 Scheduling하여 결정한다. (Long-Term 은 들어가기가 어려운 우리나라의 취업 시스템, Mid-Term은 짜르기가 쉬운 미국 취업 시스템이라고 생각하자)

 

 

자 그럼 여기서 Process State 에 대한 생각을 조금 확장시켜볼 필요가 있다. 

 

확장된 Process State Flow

 

Swapper에 의해서 메모리에서 디스크로 강등된 프로세스는 무슨 상태일까?

Running State 은 당연히 아니다. Ready State도 아닌 이유는, 주소 공간을 빼앗겼기 때문이다. Waiting State도 IO를 기다리거나 자진해서 나간 것이 아니기 때문에 아니다. 그럼 exit 된걸까? 그렇지 않다. 메모리 디스크에 있는 상태도 죽은 상태는 아니기 때문이다.

 

Suspended State

 

외부에서 (사용자 혹은 Swapper) Process를 강제로 정지시켜, 메모리에 Loading되어 있지 않은 상태를 말한다 (디스크로 Swap out). Waiting (Bloock) State은 자신이 요청한 일을 하면서 기다리는 거고, 언제든 완료 된다면 Ready State에 줄 설 준비가 되어 있다. Suspended State 은 반면에 외부에서 정지를 시켜놨기 때문에 외부에서 다시 재개를 시켜줘야 Ready State으로 돌아갈 수 있다. 

 

위의 그림처럼 Process 자체가 어디에서 무슨 일을 하고 있는지에 따라 3가지 State로 나누었는데, 더 큰 관점으로  Memory에 Loading이 되어 있는지, 안되어 있는지에 따라 Active, In-active State으로 구분을 지을 수 있다. 즉, 기존 3가지 State은 모두 Active State이다. In-active State은 예상할 수 있겠지만 Swap out이 된 Process들을 말하며, Waiting State 도중 Swap out 된 Process 는 Suspended Blocked, Ready State 도중 바뀐 Process는 Suspended Ready State 라고 부른다. IO를 기다리다가 Swap out 되어서 Suspended Blocked State가 된 Process가 나중에 IO가 끝날 경우, Suspended Ready State으로 변경된다. 

(이처럼 해당 Process 가 그렇게 된 사실을 알고 있다는 것 자체가, Process가 Exit 된 거랑은 아예 다르다. PID가 있어야 하기 때문이다. 또한, IO가 끝난다고 해서 Active 상태로는 돌아갈 수 없다. 반드시 외부의 Action으로 인해 재개가 되어야 하는 점을 알 수 있다)

 

이해가 안되었다면.. 다시 한번 다음 내용 정도로만 정리해보고 넘어가자. 나중에 다시 읽고 이해하고 넘어갈 수 있으면 좋겠다. 

 

 

"Process는 Active 한 상태에서는 3가지 State으로 나뉘며, 이는 각 State의 Queue를 둬서 운영체제가 관리한다. Queue는 PCB 위치를 줄 세워 놓고, Data Segment 내에 저장해둔다"

"CPU를 다른 프로세스로 넘길 때 문맥 교환이 일어나는데, H/W 저장값들이 (PC,SP 등) PCB Stack에 저장되고, 다른 PCB Stack이 로딩되며 발생한다"

"OS에는 Degree of Multiprogramming을 위한 Scheduler가 있고, 우리가 쓰는 시스템에는 Mid-term 스케줄러를 사용한다"

"Mid-term 스케줄러는 Process들을 메모리에서 내쫓아서 디스크로 보내고, 이를 In-active State (Suspended State)라 한다"

 

 

 

(2)  Thread

 

 

Thread의 정의는 Process 내부의 수행 단위이다. Process 가 일꾼이라면, Thread는 일을 할 수 있는 손, 발 이라고 생각하면 편한 것 같다.

주소공간과 PCB 내의 Thread들이 공존하는 모습

 

Process 가 생성되면 OS는 주소 공간을 생성한다. 이 때 불필요한게 많으면 Memory Loading이 아니라 Swap Device에 올려놓기도 한다. 또한, 이 때 OS는 Kernel 주소공간내의 Data Segment에 해당 Process의 메모리 블럭 PCB를 만든다고 했다. 

 

같은 일을 하는 Process를 여러 개 띄워놓는다면 이는 메모리 공간을 낭비하는 원인이 될 것 이다. 따라서, 같은일을 하는 프로세스가 n개 필요하다고 하면 주소 공간을 하나 띄워놓고 각 프로세스 마다 다른 수행을 할 수 있도록 해주는 것을 Threading 이라고 한다. 즉, 자원은 공유하되, 프로세스 하나에 CPU 수행 단위를 여러 개 두고 있는 것이다. 이전 PCB 그림과 위 그림을 비교해보면 알 수 있듯이, Thread는 수행하는 value들이 저장되는 레지스터들과 Program Counter 묶음을 한 CPU 수행단위로 갖고 여러 개의 수행 단위를 가지고 있는 모습을 한다고 볼 수 있다. CPU 수행 단위를 여러 개 두기 때문에, 실행 함수가 누적되는 Stack Segment 도 Thread의 갯수만큼 저장된다고 볼 수 있다 (좌측 그림). 

(Program Counter는 Process (Thread)를 수행하려면 현재 이 Process(Thread)의 어디를 수행하고 있는지 정확히 알아야 하며, 수행하기 위해 CPU Register에 현재 어떤 값들이 들어가고 있는지 알고 있어야 한다)

 

이처럼 Thread 가 CPU 수행 단위로써 독립적으로 가지고 있어야 하는 값들은 1) PC    2) Register Value Stack    3) Stack Seg 로 정리될 수 있다. 반면에 Thread가 동료 Thread들과 공유할 수 있는 값들은 1) Code Seg    2) Data Seg    3) OS Resource 로 정리할 수 있다. 

 

Thread 를 사용하면서 얻는 장점은 다음과 같다고 하는데, 외울 필요는 전혀 없고 그냥 왜 쓰는지 체감이 되면 되는 것 같다.

 

1) 응답성 (Responsiveness) 

ex1: 웹 브라우저라는 프로세스가 쓰레드 여러개를 가지고 있으면 하나의 쓰레드가 통신 결과로 데이터들을 들고 오면서 그걸 공유 자원에 넣어 놓으면, 또다른 쓰레드는 그걸 뿌려준다.

 

ex2: 백엔드 단에서 들어오는 통신에 대한 로그들을 처리하느라 응답속도가 느려진다. 따라서, 로그를 처리하는 Global Thread 를 하나 만들어서 로그를 처리할 때마다 비동기로 Thread에게 던져놓으면 Main 응답은 계속 진행할 수 있으므로 응답속도가 개선된다.

 

2) 자원 공유 (Resource Sharing)

하나의 프로세스에서 CPU 수행 단위만 여러개 두개 되면, 자원은 쓰레드들 간 공유할 수 있어서 훨씬 효율적이다 (메모리 절약).

 

3) 경제성 (Economy) 

프로세스를 만드는 건 오버헤드가 꽤 큰 편이다 (fork에 대한 얘기로, 다음 Process 관리에서 배울 내용이다). 하지만 프로세스 안에서 스레드를 만드는 건 훨씬 작은 편이므로 훨씬 부담이 적다. 또한 context switch 가 일어날 때 프로세스 간 이동은 오버헤드가 꽤 크다. 반면에 쓰레드간 CPU 전환 역시 이루어질텐데, 동일한 주소 공간 안에서 사용되고 있기 때문에 훨씬 쉬운편이다.

 

4) MP(Multi-Processor) Architecture Utilization

Multi-Core 일 때 쓰레딩을 함으로써 얻을 수 있는 장점으로, 다른 프로세서 끼리 병렬적으로 각 스레드가 일을 수행할 수 있다. (사실 [병렬적 수행으로 인한 이득]이 무슨 내용인지 정확하게 이해하지 못했다)

 

 

지금까지 쓰레드를 프로그래밍 할 때 정확하게 이해를 하지 못하고 그냥 다른 일 시키는건가보다 하면서 사용하는 경향이 컸던 것 같다. 왜 이 쓰레딩을 하는지 이해하고, 동기, 비동기식으로 어떻게 잘 사용해서 성능 개선에 영향을 줄 수 있을지 생각하면서 프로그래밍을 하는 것이 좋을 것 같다. 마지막으로 쓰레드의 종류들을 알아보자.

 

 

1) Kernel Thread : OS를 통해 지원됨. 쓰레드가 여러 개 있다는 사실을 OS가 알고 있는 Thread를 말한다. 하나의 쓰레드에서 다른 쓰레드로 CPU가 넘어가는 것도 Scheduling 되어서 넘어간다. (오버헤드가 더 큰 편)

 

2) User Thread: 라이브러리를 통해서 지원된다. 프로세스 안에서 스레드가 여러개 있다는 걸 OS가 모름. 프로그램 내부적으로 스레드가 관리가 되는 것이다. (우리가 개발을 하는 것) 커널이 볼 때는 그냥 일반적은 프로세스. 프로세스 본인이 내부에서 CPU 수행단위 여러개를 두면서 관리를 하는 것이다. 

 

 

쓰레드는 앞으로 계속 등장하므로, 그 개념과 필요성, 그리고 사용하는 이유에 대해서 잘 이해해 놓길 바란다. 

 

----------------

 

모든 출처:

 

1.이화여자대학교 반효경 교수님 운영체제 수업 (14학년도 1학기 수업)

http://www.kocw.net/home/m/search/kemView.do?kemId=1046323 

 

 

운영체제

운영체제는 컴퓨터 하드웨어 바로 위에 설치되는 소프트웨어 계층으로서 모든 컴퓨터 시스템의 필수적인 부분이다. 본 강좌에서는 이와 같은 운영체제의 개념과 역할, 운영체제를 구성하는 각

www.kocw.net

 

2. 서울대학교 홍성수 교수님(RTOS Lab) 운영체제 수업 (S-DS 수업 자료)

728x90