본문 바로가기
학교 강의/운영체제

[Chapter 3] Process

by dustnn 2025. 4. 19.

interrupt 별로 어떤 루틴을 처리해야 하는지 적어놓음

 

컴퓨터시스템 구조의 흐름 알고 있을 것

 

<Timer>

A, B, C프로그램이 있다고 할 때 세 프로그램이 돌아가면서 써야 공평함. round loading 방식

 

2번 interrupt가 들어오면 

 

- 정해진 시간이 흐른 뒤 운영체제에게 제어권이 넘어가도록 인터럽트를 발생시킴 => 타이머에서 신호가 왔다고 판단

- 타이머 값이 0이 되면 타이머 인터럽트 발생

- CPU를 특정 프로그램이 독점하는 것으로부터 보호(round robing) -> 스케줄링

=> time sharing을 구현하기 위해 널리 이용

=> 현재 시간을 계산하기 위해서도 사용됨

 

Memory부분이 ISR

 

CPU 로 들어가기 전 interrupt line에는 스케줄러가 존재.

스케줄러에 따라 device driver를 작동(?)

device driver가 device controller에게 신호 보냄

 

device controller

: 작은 CPU라고 보면 됨.

- I/O device controller

: 해당 I/O 

: 실제 디바이스와 local buffer 사이

일단 local buffer로 쏴주면 device controller가 I/O 끝났을 대 추출해 CPU로 보냄(인터럽트)

 

 

 

입출력의 수행

 

모든 입출력 명령은 특권 명령(OS만이 특권명령을 사용할 수 있도록 제한해둠)

사용자 

 

시스템콜: 사용자 프로그램은 운영체제에게 I/O 요청

=> 특권명령이란 시스템콜

 

DRAM 안에서..

read라는 명령어로 시스템콜 하면

OS로 그 명령어가 옮겨옴

 

 

trap(소프트웨어적 interrupt)을 사용하여 인터럽트 벡터의 특정 위치로 이동

read() -> mode bit이 0으로 바뀌면서 모니터 모드 -> 키보드의 인터럽트 벡터 찾아가

-> 키보드의 Interrupt service routine의 2번을 콜 -> 키보드의 device driver에게 키를 읽으라고 요청 -> 실제 키보드로 신호 보내 작업 수행

 

interrupt당한다는 것은 OS로 넘어간다는 것

interrupt -> CPU 현황 정보(레지스터, program counter)를 save한 후 os로 넘어감 -> CPU 제어를 ISR에게 넘김

 

(넓은 의미) 인터럽트 중요

하드웨어 인터럽트: 키보드의 'a'를 누른 것과 같은

소프트웨어 인터럽트: 두 종류의 원인(exception, system call)

- Exception(): 오류가 발생했을 때 system call을 부른 것처럼 trap을 발생시켜 정리 작업 수행

- system call(): 커널함수 (read() 와 같은)

 

 

ISR: 인터럽트 서비스 루틴의 포인터를 가지고 있다.

 

harddisk가 인터럽트를 걸면 CPU가 harddisk에 해당하는 

 

동기식 입출력 & 비동기식 입출력

 

 

getche() -> read() -> 키보드 콜

 

키가 들어와야 응답

둘 다 하드웨어로부터 입력을 받을 때 인터럽트 발생

 

<동기식 입출력(Synchronous call)>

; 하드웨어와 발맞춰(I/O 요청 후 입출력 작업이 완료된 후에야 제어가 사용자 프로그램에 넘어감)

read() 명령어를 거쳐 device driver로 감 -> 키보드 -> 리턴

 

구현방법1)

I/O가 끝날 때까지 CPU를 낭비시킴

매 시점 하나의 I/O만 일어날 수 있음

 

구현방법2) 개선

 

 

ex. 한글 을 BLOCKED 상태로 만들고 기다리게 함

 

<비동기식 입출력(Asynchronous call)>

: 하드웨어와 따로

프린터를 예로 들 때

print() 콜하면 다시 user에게 돌아오고

print 완료됐다는 것을 따로 알려줌(이것이 인터럽트 !!)

 

I/O가 시작된 후 입출력 작업이 끝나기를 기다리지 않고

cpu를 바로 쓰기 때문에 

"완료되면 인터럽트로 알려줘. 그 전까지 다른 일 하고 있을게"

 

DMA(Direct Memory Access)

 

- 빠른 입출력장치

- CPU의 중재 없이 device controller가 device의 buffer storage 의 내용을 메모리에 블록 단위로 직접 전송

CPU를 통과해 harddisk까지 가면 CPU 낭비

단순 전송이면 CPU 개입이 필요 없잖아. -> CPU가 primary memory(DRAM)에게 harddisk로 바로 쏘고 자신에게 보고해달라고 함

블록 단위로 쏘고 끝나면 인터럽트 발생시켜서 나한테 알려줘.

 

서로다른 입출력 명령어

 

메모리에 접근하는 방식으로 

메모리는 잠시 숨겨져 있음

 

0~10000: primary memory

10001~10100: 키보드

10101~10200: disk

10201~10300: 마우스

 

이부분까지는 조금 설렁설렁 들었음

프로그램의 실행(메모리 load)

: Linus, Window 공통 (중요)

 

컴파일

-> [File system]A.exe (바이너리 기계어 파일, addressing된 상태)

-> [Virtual memory]각 프로세스의 Code, Data, Stack 만들어짐

-> [Physical memory]DRAM 메모리에 각각 로딩

 

커널도 일종의 프로세스이기 때문에

* 커널 어드레스 스페이스는 virtual memory의 개념을 쓰지 않고 real address 시스템을 씀(커널은 실제 address를 알고 있어야 하기 때문에)

* 반면.. 프로세스A,B의 address space는 virtual memory의 개념을 씀

 

- virtual memory

: 실제 공간x 마치 공간이 있는 것처럼 addressing만 수행(물론 가상의 주소)

addressing은 무조건 0번지부터

코드 영역/데이터영역/스택영역

 

프로세스 A, B가 있고

physical memory(DRAM)에서 A는 1000번지부터, B는 2000번지부터 시작한다고 할 때

address translation에선 A+1000, B+2000

"swapping": harddisk의 영역을 마치 메모리처럼 사용하는 것

=> DRAM 메모리가 부족한 경우 안 쓰는 부분을 하드디스크로 백업해서 DRAM의 공간을 확보함

=> 여러 개의 application 실행 가능

 

하드디스크를 제2의 DRAM으로 활용하기 때문에 프로세스가 많아질수록 속도가 느려짐

 

커널 주소 공간의 내용

 

<code 영역>

DRAM 메모리는 비싸고 공간 한계가 있는데 돌려야 할 프로세스는 많음 => virtual memory

 

커널이라는 프로그램이 작동

 

시스템콜, interrupt 처리 코드

자원 관리를 위한 코드: 

편리한 서비스 제공을 위한 코드

 

<data 영역>

프로세스는 살이있는 프로그램

프로세스도 프로그램이기 때문에 관리해줘야

- PCB(Process Control Block)-중요

프로세스와 관련된 정보를 저장하고

프로세스가 잘 돌아가고 있는지 관리, 제어

 

- CPU 위에 OS가 얹혀 돌아감(code)

공간은 data 영역(ex. CPU를 잠시 쉬게 해야 겠다 등등)

 

<stack 영역>

A 내부에서 부르면 A의 스택에 쌓이다가 system call(read())하는 순간 kernel 스택(kernel 안의 스택)으로 복사됨

-> 이후 kernel의 코드를 콜하게 될 때는 kernel stack에 쌓이게 됨

 

 

A() 콜 -> 사용자 정의 함수

 

printf() -> 라이브러리 함수

 

A프로그램(커널모드)이 작동하다가 시스템콜하는 순간(write()가 호출되는 순간) kernel모드로 들어감

 

<A의 스택의 address space>

: A 사용자 모드일 때(library 쓰는 것까지 포함)

main
a()
printf()

 

<A kernel stack의 address space>

 

 
 
 

 

a.exe -> DRAM 의 code에 정보 저장 DRAM의 kernel

프로세스(살아 있는 프로그램)

CPU

 

 

user mode와 kernel mode를 왔다갔다 하면서 진행

 

프로세스 개념 & 상태
프로세스의 개념

 

프로세스의 context문맥(프로세스의 일대리라고 보면 됨) - 굉장히 중요

다음은 모두 context에 포함된다.

 

1. CPU 수행 상태를 나타내는 하드웨어 문맥

 

- Program counter(중요)

Program counter라는 레지스터는 프로세스의 상태 정보 저장 공간(몇 번째 코드를 사용하고 있는지에 대한 정보 저장)

ex. 2번에서 5번으로 바꾸면 Jump와 같은 기능

 

- 각종 register

ADD $3, $1, $2

프로세스의 현재 연산 상태를 가지고 있기 때문에

 

 

2. 프로세스의 주소 공간

- code

code 대로 프로세스가 진행되기 때문에

- data

global/static variable 저장 => 프로세스 설명해주는 자료가 됨

- stack

system call, malloc 등 저장

 

3. 프로세스 관련 커널 자료 구조

- PCB

운영체제가 각 프로세스를 관리하기 위해 프로세스당 유지하는 정보

프로세스 하나당 PCB 1개 -> CPU, memory 사용 현황 저장하고 있음

 

- kernel stack

 

프로세스의 상태

 

- Running

: CPU를 잡고 기계어를 수행 중인 상태

 

- Ready

: CPU 할당을 기다리는 상태

 

- Blocked(wait, sleep)

: CPU 할당돼도 당장 사용할 수 없는 상태

: I/O 등의 이벤트를 스스로 기다림

ex. I/O device에서 파일 읽어와야 할 때 결과를 기다리는 경우

ex. 키보드 입력을 받아야 다른 명령어를 실행할 수 있을 때

 

=> 자신이 요청한 event가 만족되면 ready

 

- Suspended

: 외부적인 이유로 프로세스 수행이 정지된 상태(메모리에 프로세스 너무 많아 정리)

ex. 중기 스케줄러에 의해 메모리에서 out됐을 때

 

=> 외부에서 resume해주어야 active

 

- New

: 프로세스가 생성 중인 상태

- Terminated

: 수행이 끝난 상태

각 프로세스의 PCB는 kernel의 data 영역에 저장된다
프로세스 상태도


<작업 순서>

new -> ready(ready queue에 줄 서있음) -> running(CPU에 들어가면)

harddisk에 작업 요청하면 CPU에서는 running -> blocked 상태(harddisk는 속도가 느리기 때문에)

-> harddisk가 작업 완료 -> CPU blocked -> running 상태로 돌아옴

 

=> running ready blocked 상태 왔다갔다 함

PCB(Process Control Block)

 

: 프로세스를 관리하기 위해 OS가 kernel address의 data 부분에 놓음(각 프로세스 당 하나씩)

 

PCB의 구성요소

 

1. OS 가 관리상 사용하는 정보

- process state: OS가 지속적으로 모니터링

- process ID: 인덱싱해서 저장해놓음

- scheduling information: FCFS. RR, STF 등등 스케줄링 방식 종류

- priority: 높은지 낮은지, 몇 번째 우선순위인지

 

2. CPU 수행 관련 하드웨어 값

- program counter

- registers

 

3. 메모리 관련

Code, data, stack의 위치 정보

 

4. 파일 관련

Open file descriptors

: 현재 열려 있는 파일에 대한 정보 -> 이미 해당 파일을 오픈하고 있는 프로세스가 있다면 다른 프로세스가 오픈하지 못하도록.

PCB

PCB 사용

 

: context switch할 때 저장/복원 위해 사용

 

‼️context switch(중요)‼️

: CPU를 한 프로세스에서 다른 프로세스로 넘겨주는 과정

 

CPU 제어권을 A에게서 빼앗아 B에게 넘기는 상황을 가정해보자.

 

커널의 data 내, B의 PCB에 B의 이전 상태를 저장하고 있었음

-> A에게서 뺴앗는다면

-> A의 PCB에 PC값과 register값을 저장

-> 제어권을 B에게 넘겨 B의 PCB 복원해 계속 수행

 

- "context switch 아닌 경우"

: system call -> 끝나면 다시 요청한 프로세스로 복귀

: interrupt

-> 잠깐만 갔다 돌아오는 것이기 때문에 context switch가 아님

 

- "context switch인 경우"

: CPU 제어권이 다른 프로세스에게 완전히 넘어갈 때

-> 저장/복원 수행해 전환하는 과정이 진행된다.

: I/O 요청 system call -> 오래 걸리기 때문에 다른 프로세스에게 CPU 제어권을 넘겨 효율 추구

: timer interrupt -> 큐에 있는 다른 프로세스에게 할당

context switch인 경우 vs 아닌 경우

 

==> 1번 경우에도 register 등의 정보는 커널을 위해 업데이트해줘야 하기 때문에 PCB에 저장되어야 하지만

2번(context switch) 경우에는 업데이트 사항 모두 저장해야 하기 때문에 오버헤드 큼.

 

프로세스 스케줄링 위한 큐

 

linked list로 구현돼 있다.

ready queue에서 process 떼어 disk에 부착 -> 끝나면 다시 ready queue로 복귀시킴

ex. time slice expired: RR 방식 -> 프로세스 할당 시간이 끝나면 뒤로 보냄

 

스케줄러

 

long-term, medium-time은 참고하기만 하고 short-term만 확실히 알 것

 

<long-term scheduler>

= 장기 스케줄러 = job scheduler

: ready queue에 보낼 것 결정해서 보냄

 

<short-term scheduler>(중요)

=단기 스케줄러 = CPU scheduler

: CPU에게 어떤 프로세스를 줄 것인지(어떤 프로세스를 running 시킬지) -> CPU 활용도 결정하므로 가장 중요

 

 

<medium-time scheduler>

=중기 스케줄러=swapper

: 여유 메모리 확보를 위해 특정 프로세스를 아예 메모리 밖으로 쫓아내기

 

Thread

 

CPU util의 기본 단위

: CPU 관련 정보만 -> lightweight process

 

(중요) thread 구성과 thread가 동료 thread와 공유하는 부분을 구분하기

 

<thread의 구성>

- program counter

- registers

- stack space

 

<동료 thread와 공유하는 부분(=task)>

- code section

- data section

- OS resources

 

 

<다중 thread>

 

T1 thread가 blocked 돼도 T2&T3가 실행되어 막힘없이 처리 가능

-> high throughput & 병렬성 증가

 

프로세스를 여러 개 만들면 되지만 왜 이렇게 할까?

프로세스를 만든다는 것은 주인을 만드는 것과 같기 때문에,

프로세스를 만드는 것은 thread를 만드는 것보다 훨씬 많은 자원을 만들어야 함(PCB, address space등..)

+ 프로세스끼리 호환도 잘 안 됨

=> thread 만드는 게 나음 !!

 

하나의 프로세스에 여러 개의 thread

-> code, data, OS resource는 공유

-> CPU 수행 관련 부분만 별도로 관리(pc, register, stack)

=> 프로세스 하나여도 여러 개의 프로그램 띄우기 가능

 

 

*process와 thread의 차이점을 중심으로 공부하기

 

<thread 장점>

1. responsiveness(반응성)

T1에 문제가 있어도 T2, T3가 작동하기 때문에

 

2. resource sharing

process간에는 호환성x

: process1이 키보드에 작업을 요청하면 키보드 응답은 process1에게만 주고 process2에게는 주지 않음

thread간에는 호환성(서로 자원 및 메모리 접근 권한)

 

3. economy

프로세스 대비 thread 생성 시에는 일부만 생성하는 것이기 때문에 비용 적음

 

4. utilization of MP(Multicore processor) architectures

: 스레드와 프로세스의 공통적인 특징

: 각 thread는 parallel하게 운영됨

 

<thread 실행>

아래 쓴 것 정도만 공부할것

- kernel threads: kernel이 지원하는 thread

: windows 95/98/NT

: LINUX

 

- user threads: library가 지원하는 thread

: POSIX Pthreads