3-1강, Process 1
프로세스의 개념
- Process is a program in execution
- 프로세스의 문맥, context
- 프로세스의 현재 상태
- CPU 수행 상태를 나타내는 하드웨어 문맥
- PC, Program Counter : 현재 어디를 가르키고 있는가, 현재 어떤 내용을 담고 있는가
- 각종 register : 어떤 인스트럭션까지 진행했는가, 어떤 내용을 담고 있는가
- 프로세스의 주소 공간
- code, data, stack : 위와 거의 동일
- 프로세스 관련 커널 자료 구조
- PCB(Process Control Block) : 운영체제가 프로세스에 대해 어떠한 정보를 담고 있는가
- Kernel stack : 커널의 함수가 실행되면 커널 함수를 부른 프로세스의 커널 스택이(A의 커널 스택) 커널 주소 공간의 스택에 쌓인다.
- 다른 프로세스로 제어권이 갔다가 현 프로세스로 돌아올 때 이러한 정보가 남겨져 있지 않으면 처음부터 다시 실행해야 한다.
프로세스의 상태
-
프로세스의 상태를 통해 타임 쉐어링이 구현된다.
-
Running
- CPU를 잡고 instruction을 실행 중인 상태
-
Ready
- CPU를 기다리는 상태(당장 물리적인 메모리에 프로그램이 올라와있는 등 CPU 제어권을 잡지 않은 것을 제외 하고는 다른 조건은 모두 만족한 상태)
-
Blocked(wait, sleep)
- CPU를 주어도 당장 인스트럭션 수행이 불가능한 상태
- I/O 등의 event를 기다리는 상태(프로세스가)
- 프로세스 자신이 요청한 event가 즉시 만족되지 않아 이를 기다리는 상태
- ex. 디스크에서 file을 읽어와야 하는 경우
-
Suspended(stopped)
- 외부적인 이유로 프로세스의 수행이 정지된 상태
- 메모리의 프로세스가 통째로 디스크에 swap out된 상태이다.
- ex.
- 사용자가 프로그램을 일시 정지시킨 경우(break key). 사람이 다시 재개 명령을 해줘야 active가 될 수 있다.
- 시스템이 여러 이유로 프로세스를 잠시 중단시킴.(메모리에 너무 많은 프로세스가 올라와 swapper에게 중재된 경우)
-
New : 지금 막 프로세스가 생성 중인 상태
-
Terminated : 프로세스 수행(execution)이 끝났지만, 할 일이 다 끝났지만 정리할 게 조금 남아 있는 상태
-
New, Terminated는 경우에 따라 추가된다.
-
Blocked와 Suspended 차이
- Blocked : 자신이 요청한 event가 만족되면 ready상태가 된다.
- Suspended : 외부에서 프로세스를 정지시켜놓은 상태로(메모리를 다 빼앗아 디스크에 넣은 상태), 외부에서 resume을 해주어야 위의 running, ready와 같은 상태가 될 수 있는 active된다.
- 하나의 프로세스만 CPU에서 돌 수 있다.
- 하나의 프로세스가 CPU에서 running하다가, 디스크에서 뭔가를 읽어와야 하면 blocked가 되면서 이 프로세스는 디스크에 가서 대기큐에 들어가게 된다. 그 작업이 끝나면 disk controller가 CPU에게 인터럽트를 걸게 되고(방금 요청한 그 프로세스의 I/O 작업이 끝났다고 알림) CPU는 하던 다른 작업을 멈추고 제어권이 커널에게 넘어가게 된다. 그러면 디스크의 데이터가 메모리 영역에 넘겨지는 작업을 수행하기도 하고 ready queue에 프로세스를 넣어 CPU 제어권을 얻게 해준다. 키보드 입출력을 받아들이는 과정도 유사하다.
- 어떤 프로세스가 공유 데이터를 접근하고 있으면, 그 프로세스로 인한 결과가 나올 때까지 다른 프로세스가 접근하는 것을 block한다. 즉 resource queue에 넣는다.
- 놀이동산에서 줄을 서가면서 기구를 기다리고 타는 과정과 유사하다.
- 기구를 타는 시간(running)은 빠르나 기다리는 시간(block)은 길다.
- 하드웨어 작업은 CPU 연산보다 100 ~ 1000만배 느리다.
- 모든 자원들이 놀지 않고 다 잘 일을 할 수 있게 해주는 메커니즘이 필요해진다.
- queue라는 것은 커널 주소 공간의 data 영역에 자료 구조로 queue를 만들어 놓고 사용하는 것이다.
PCB, Process Control Block
- 운영체제가 각 프로세스를 관리하기 위해 프로세스 하나당 유지하는 정보
- 구성 요소
- PCB들을 연결할 수 있는 Pointer
- OS가 관리상 사용하는 정보
- Process State(ready, running, wait 등), Process ID(프로세스만의 ID)
- scheduling information priority(프로세스한테 CPU를 주기 위한 우선순위 관련 정보)
- CPU 수행 관련 하드웨어 값(프로세스 문맥을 표시하기 위한 정보)
- Program counter, registers(어떤 정보를 담고 일하고 있었는가)
- 메모리 관련
- code, data, stack의 위치 정보(물리적 메모리에서 어디에 위치하고 있는가)
- 파일 관련
- Open file descriptors(프로세스가 오픈하고 있는 파일은 어떤 것들이 있는지)
문맥 교환(Context Switch)
- CPU를 한 프로세스에서 다른 프로세스로 넘겨주는 과정이다.
- CPU가 다른 프로세스에게 넘어갈 때 운영체제는 다음을 수행한다.
- CPU를 내어주는 프로세스의 상태를 그 프로세스의 PCB에 저장한다.
- CPU를 새롭게 얻는 프로세스의 상태를 PCB의 정보를 읽어온다.(다시 그 프로세스가 실행될 때 어디서부터 어떻게, 어떤 걸 수행하는지 다시 기억해내기 위해서. timer interrupt를 통해서 중간에 끊겼을 수도 있으니까)
- PCB는 커널 주소 공간의 stack에 위치하고 있다.
- 사용자 프로세스로부터 CPU가 운영체제로 넘어가는 것을 컨텍스트 스위칭이라고 하지 않는다.
- 사용자 프로세스로부터 다른 프로세스로 넘어가는 것이 컨텍스트 스위칭이다.
- 즉, 시스템 콜이나 인터럽트 발생 후 반드시 컨텍스트 스위칭이 일어나는 것은 아니다. (1)과 같은 경우가 있다. 이 때는 컨텍스트 스위칭이 아니다.
- (2)에서는 timer interrupt가 들어왔다. timer 자체가 다른 프로세스로 넘기기 위함이다. 따라서 컨텍스트 스위칭이 일어난다고 말할 수 있다. 또한 I/O 작업과 같은 오래 걸리는 작업이 들어오면 그 프로세스한테 다시 CPU를 줘도 당장 그 프로세스의 진행이 불가하다. I/O 작업 결과를 받기 전까지는.
- (1)의 경우에도 CPU 수행 정보 등 CPU 문맥의 일부를 당연히 커널 주소 공간의 data에 있는 자신의 PCB에 정보를 저장한다. 하지만 (2) 경우보다는 부담이 훨씬 작다.
- ex. cache memory flush(상당한 오버헤드)
- 보통 컨텍스트 스위칭이 일어나면 원래 프로세스가 사용하던 캐시 메모리를 다 지워버려야 한다.
- (1)의 경우에는 어차피 본인 프로세스로 넘어오니 캐시 메모리를 비울 필요가 없다.
프로세스를 스케줄링하기 위한 큐
- Job queue : 현재 시스템 내에 있는 모든 프로세스의 집합
- Ready queue : 현재 메모리 내에 있으면서 CPU를 잡아서 실행되기를 기다리는 프로세스의 집합
- Device queue : I/O device의 처리를 기다리는 프로세스의 집합
하드 디스크의 서비스를 받기 위해 PCB들이 기다리고 있다.
프로세스 스케줄링 큐의 모습
- I/O request의 경우, 오래 걸리기 때문에 스스로 CPU 제어권을 놓게 된다.
- wait for an interrupt도 마찬가지다. I/O 작업 말고도 오래 걸리는 작업을 하게 되는 경우다.
스케줄러(Scheduler)
-
Long-term scheduler(job scehduler)
- 시작 프로세스 중 어떤 것들을 ready queue로 보낼지 결정한다.
- 프로세스한테 메모리를 줄지 결정한다. 즉 프로그램을 시작시켜도 곧바로 메모리를 주지 않을 수도 있다.
- 위 그림에서 new 상태에 있는 프로세스한테 메모리를 줄지 안 줄지(ready로 바꿀지(admitted) 결정하는 것이다.
- degree of Multiprogramming을 제어
- 메모리에 프로그램이 몇 개 올라가있는지를 제어하는 것이다.
- 메모리에 올라가있는 프로세스의 수
- ex. 프로세스 3개에게 메모리를 주고 있는 상태이면 degree of Multiprogramming은 3
- 너무 많이 올라가도, 적게 올라가도 성능이 안좋아진다.
- 적게 올라가있으면 CPU가 놀게 된다.
- 너무 많이 올라가있으면, 그 프로세스에 대한 데이터가 메모리에 조금만 올라가 있을 수 있다. 이럴 경우 CPU가 해당 프로세스에서 작업을 수행할 때 원하는 데이터가 없기 때문에 I/O 작업(시간이 오래 걸리는)을 요청하게 될 수 있다.
- 프로그램을 실행시켜나도 장기 스케줄러가 자기 마음에 드는 어떤 프로세스한테만 메모리를 줘서 실행가능하게(ready) 만들어준다.
- 현재는 프로그램을 실행하면 곧바로 ready 상태가 들어간다. 즉 장기 스케줄러가 없다. degree of Multiprogramming 제어는 중기 스케줄러가 맡게 된다.
-
Short-term scheduler(CPU scheduler)
- 굉장히 짧은 단위로 스케줄링이 일어난다.(millisecond 단위)
- 어떤 프로세스한테 CPU를 줄지(running 시킬지) 결정한다.
- 충분히 빨라야 한다.
-
Medium-term scheduler(swapper)
- 현재 time sharing system에서는 보통 장기 스케줄러가 없어서 프로그램이 실행되면 곧바로 메모리를 주게 된다.(메모리에 올라가게 된다)
- 하지만 메모리에 너무 많이 프로그램이 올라가있으면 문제가 되는데, 이를 swapper가 해결해준다.
- 여유 공간 마련을 위해 일부 프로세스를 골라 통째로 메모리에서 디스크로 쫓아낸다.
- 어떤 프로세스로부터 메모리를 뺏을지 결정해야 한다.
- degree of Multiprogramming을 제어하게 된다.
- 시스템 입장에서는 더 효과적이다.
프로세스 상태도
- Running(monitor mode)에서는 운영체제가 running 하고 있다고 표현하는 것이 아니라, 사용자 프로세스가 커널 모드에서 running하고 있다고 표현한다. 이를 유의해야 한다.
- Suspended는 메모리를 완전히 잃어버리는(swap out) 상태이다.
- CPU 관점에서는 이 상태에서 아무것도 할 수 없다.
- I/O 작업이 진행 중이었고, 그것이 완료되면 Suspended Block에서 Suspended Ready로는 갈 수 있다.
3-2, Process 2
Thread
- CPU를 수행하는 단위
- 프로세스 내부에 CPU 수행 단위가 여러 개인 경우를 쓰레드라고 부른다.
- 처음엔 그냥 수행 단위가 프로세스 1개인 거고, 수행 단위가 2개 이상 되면 쓰레드라고 부르는 걸까?
- CPU가 코드의 어느 부분을 실행 준인가, 즉 프로그램 카운터(PC)만 여러 개 두는 것.
- 프로세스 하나에 CPU 수행 단위만 여러 개 두고 있는 것을 쓰레드라고 부른다.
- CPU 수행을 위해서(인스트럭션 수행을 위해) code의 어느 부분을 가르키는지 저장하고 있는 PC가 필요하다.
- CPU 수행을 한다는 것은 register에 어떤 값을 넣고 실행하는 것이니 별도로 register 또한 필요하다.
- 쓰레드 하나가 코드 어느 부분을 실행하다가, 함수를 호출하면, 그 함수를 호출하고 리턴하는 관련된 정보를 스택에 쌓아야 한다. 이러한 stack도 별도로 가지게 된다.
- 즉 쓰레드는 메모리 주소 공간을 공유하고(프로세스 내에 있는 것이 쓰레드이니, 그리고 그 프로세스에서 수행하는 것이 쓰레드이고 그 프로세스의 데이터를 공유해야 한다) 프로세스 하나에 여러 개의 쓰레드이니 PCB 하나(프로세스 상태, 프로세스가 사용하는 각종 자원들(파일들 등) 등)를 공유한다.
- PC나 register, stack은 쓰레드가 각자 가지게 되고, 나머지 PCB 정보나 주소 공간은 쓰레드들 끼리 공유하게 된다.
- 쓰레드의 구성, 쓰레드 1개가 각자 가지는 것들
- Program Counter
- register set
- stack space
- 쓰레드가 동료 쓰레드와 공유하는 부분(다른 말로는 task라고 한다)
- code section
- data section
- OS resources(각종 자원들?)
- 하나의 프로세스 안에 쓰레드가 여러개 있으면 task는 1개만 존재한다고 말할 수 있다.
- lightweight process 라고도 부른다.
- 프로세스를 별도로 두는 것보다, 프로세스 안에 쓰레드를 여러 개 두는 것이 훨씬 더 메모리 낭비가 적어 가볍기 때문이다.
- 반면 전통적인 프로세스는 heavyweight process라고 부른다.
쓰레드의 장점
- 응답 시간이 빨라진다.
- 다중 쓰레드로 구성된 task 구조에서는, 하나의 서버 쓰레드가 blocked(waiting) 상태라도, 동일한 task 내의 다른 쓰레드가 실행(running)되어 빠른 처리가 가능해진다.
- ex. 어떤 쓰레드가 서버로부터 정보를 가지고 오고 있다면, 다른 쓰레드가 일단 텍스트라도 화면에 띄우는 일을 하게 됨으로써 사용자는 더 빨리 정보를 받을 수 있다.
- 프로세스가 하나 더 만들어진 독자적인 주소 공간이 또 필요해지므로 메모리가 낭비된다. 하나의 프로세스 안에 쓰레드를 늘리게 되면 프로세스를 하나 더 만드는 것보다 낭비가 적어진다.
- 다중 쓰레드가 협력하여 높은 처리율과 성능 향상을 얻을 수 있다.
- CPU가 여러 개 달린 컴퓨터인 경우, 쓰레드를 사용하면 병렬성을 높인다.
- 각 쓰레드들이 다른 CPU에서 움직이게 되고, 행렬 곱셈의 경우 더 빨리 결과를 얻을 수 있다.
- 쓰레드에 대한 정보는 PC, register와 같은 독자적인 정보만 PCB에 존재하면 되기에 수십 바이트 정도만 필요하다.
3-3강, Process 3
single and multithreaded processes
쓰레드의 장점
- Responsiveness, 응답성이 빠르다.
- ex. multi-threaded Web
- 웹 브라우저를 띄워놓고, 포털 사이트에 홈페이지 주소를 입력하면 HTML 문서가 날라온다.
- 화면에 디스플레이할려고 봤더니 HTML 문서 안에는 임베디드된 이미지들이 있다.
- 웹 브라우저가 이 이미지들을 해석하여 다시 서버에 요청한다.
- 이미지가 다 도착하면 화면에 텍스트와 이미지가 보이게 된다.
- ############################################
- 이미지를 다시 서버에 요청하는 작업이 오래 걸리므로 그 프로세스를 보통 Block시킨다.
- 사용자 입장에서는 답답함을 느끼게 된다. 화면에 아무것도 디스플레이되지 않으니.
- 그렇게 하지 않고 여러 개의 쓰레드를 사용하게 되면, 먼저 HTML 문서를 가져오고 나서 임베디드된 이미지를 다시 요청한 순간에
- 요청한 그 쓰레드만 block시키고, 다른 쓰레드가 HTML 문서의 텍스트라도(이미지를 불러오는 작업과 무관하다) 디스플레이에 출력시킨다.
- 그러면 사용자 입장에서는 답답함을 덜게 느낄 수 있다.
- 비동기식 입출력이라고도 할 수 있다.
- Resource Sharing, 자원을 공유할 수 있다.
- n개의 쓰레드는 binary code, data, resource of the process를 공유할 수 있다.
- Economy, 경제성
- 프로세스를 하나 만드는 것은 오버헤드가 상당히 크다.
- 프로세스 하나 안에 쓰레드를 하나 추가하는 것은 그다지 오버헤드가 크지 않다.
- Context Switching을 하는, 즉 프로세스가 바뀌는 것은 오버헤드가 크다. 하지만 동일한 프로세스 내에서 쓰레드 간의 CPU Switching은 아주 간단하다. 대부분의 문맥을 그대로 사용할 수 있다.
- Solaris의 경우, 프로세스를 생성하고 프로세스끼리 스위칭하는 것이, 쓰레드가 생성되고 쓰레드끼리 스위칭하는 것보다 각각 30배, 5배 정도 오버헤드가 크게 발생한다.
- Utilization of MP Architectures, CPU가 여러개 있는 경우(Multi-processor)
- 각각의 쓰레드가 서로 다른 CPU에서 병렬적으로 일을 할 수 있게 된다.
- 결과를 더 빠르게 얻을 수 있다.(굉장히 큰 행렬 곱셈을 하는 등)
Implementation of Threads
- kernel threads는 kernel이 쓰레드의 존재를 알고 있다.
- user threads는 커널의 지원을 받지 않고 사용자 수준에서 구현되는 것이다. 커널은 쓰레드의 존재를 모른다.
팀 스터디 간 얻은 지식
- 오버헤드(overhead) : 어떤 처리를 하기 위해 들어가는 간접적인 처리 시간 · 메모리