본문 바로가기
CS

[OS] 운영체제 질문 - (프로세스,스레드,동기화 문제,교착상태,페이징,가상메모리)

by onejunu 2022. 6. 15.

질의응답 형식으로 면접하듯이 정리해봤습니다.

아무리 잘 아는 질문이라고 해도 막상 대답하려고 하면 어려운거 같습니다.

완벽히 아는게 아니라는걸 알려주는거 같기도합니다.

스스로 질문해보고 응답해보면 기억에 잘 남는거 같습니다.

 


 

프로세스가 무엇인가요?

- 프로그램이 메모리에 적재되어 CPU를 할당 받아 실행되는 것을 프로세스라고 합니다. 즉, 실행중인 프로그램입니다. 프로그램은 명령어들이 포함된 파일입니다.

 

프로세스의 구조가 어떻게 되나요?

- 프로세스에는 4가지 영역이 있습니다.

1) 코드 : 말 그대로 코드 자체가 저장되는 메모리입니다.

2) 데이터 : 전역변수,static 변수들이 저장되는 메모리입니다.

3) 힙 : 직접 공간을 할당하고 해제할 수 있는 메모리 영역입니다. 자바의 경우 실제 객체 인스턴스를 저장합니다.

4) 스택 : 스택영역은 함수 호출시 생성되는 지역변수와 매개변수가 저장됩니다. 지역변수와 매개변수는 힙영역에 실제 인스턴스가 있을 수 있는데 이때 이 객체를 참조하는 변수들이 될 수 있습니다. 

 

 

CPU를 할당 받은 프로세스의 실행과정은 어떻게 되나요?

- 프로세스의 코드영역을 CPU가 연산을 해갑니다. 코드 영역의 명령어를 가져오기 위해서 다음 실행할 명령어의 주소값을 저장하고 있는 PC레지스터가 있습니다. PC레지스터는 코드영역의 명령어중 바로 다음 실행할 명령어를 저장하고 있는데 이로 인해 명령어가 진행되면서 프로세스가 실행됩니다.

 

멀티 프로세스가 무엇인가요?

- 멀티프로세스란 2개 이상의 프로세스가 동시에 실행되는 것을 의미합니다. "동시에" 라는 부분의 정의가 좀 더 명확해지기 위해서는 동시성과 병렬성의 차이를 이해해야 합니다.

 

동시성 vs 병렬성 은 어떤 차이인가요?

- 동시성은 Concurrency 입니다. 하나의 코어가 여러 프로세스를 번갈아가며 실행해서 실제로는 하나씩 실행되지만 동시에 실행되는 것처럼 보이는 것을 의미합니다. 이를 시분할 시스템이라고도 합니다.

- 병렬성은 Parallelism 입니다. 여러개의 코어가 각각 프로세스를 담당하며 실제로 여러 프로세스가 동시에 실행되는 것을 의미합니다.

 

위 처럼 프로세스가 3개인 경우 3개의 프로세스가 CPU를 번갈아 가면서 할당받게 됩니다. 그렇다면 CPU는 어떻게 프로세스들의 다음 명령어나 상태등을 알까요? 이는 커널영역의 PCB를 통해 프로세스의 상태들이 저장됩니다.

 

PCB가 무엇인가요?

- Process Control Block 입니다. 운영체제에서 프로세스들의 정보를 관리하기 위한 자료구조이며 CPU가 연산을 이어가기 위해 필요한 정보들이 들어있습니다. PCB에는 중요한 정보가 담겨있으므로 일반 메모리에 저장하면 안되며 보통 보호된 메모리 영역안에 저장됩니다. 보호되는 메모리로 대표적인 커널영역이 있습니다.

 

- PCB에는 다양한 정보들이 담겨있습니다. 대표적으로 프로세스의 상태와 프로세스의 번호, 프로그램 카운터(PC) , 다양한 레지스터 값등이 있습니다.

 

멀티 프로세스들이 실행되는 과정을 간략하게 표현해주세요.

- 프로세스1이 실행되고 마무리되었을때를 시작으로 그림으로 표현하면 아래와 같습니다. 프로세스1의 정보들을 PCB1에 저장합니다. 그림상으로는 PC레지스터 밖에 없지만 실제로는 많은 저장요소들이 있습니다.

- 다음에 실행할 프로세스2의 정보들을 CPU의 레지스터들에 저장합니다. 

- CPU 연산을 진행합니다. 연산중 할당된 시간이 끝나면 CPU 정보들을 다시 PCB2에 저장합니다.

 

위와 같은 과정들을 무엇이라고 부르나요?

- 이처럼 CPU의 제어권을 한 프로세스에서 다른 프로세스로 넘겨주는 것을 문맥교환(Context Switch) 라고 합니다. 한 프로세스의 PCB를 저장한 후 다른 프로세스의 PCB를 불러와 CPU 연산을 진행합니다.

 

 

프로세스의 상태도 저장된다고 했는데 프로세스의 상태는 어떤것들이 있나요?

- 실행 : CPU를 점유하고 있는 상태이며 실행되고 있는 상태입니다.

- 준비 : CPU만 할당 받는다면 즉시 수행가능합니다.

- 봉쇄 : CPU할당 받아도 실행못하는 상태입니다. 예를 들어 입출력 작업은 CPU가 할 수 있는일이 없기 때문에 다른 장치로부터 신호가 와야합니다.  

 

스레드가 무엇인가요?

- 스레드는 하나의 프로세스 내에서 실행되는 동작의 단위입니다. 각 스레드는 프로세스의 스택메모리를 제외한 나머지영역인 코드,데이터,힙 영역을 공유합니다.

 

- 스레드는 프로세스 내에서 독립적인 기능을 수행합니다. 이는 독립적인 함수를 호출함을 의미하며 따라서 스택메모리가 별도로 필요합니다. 스택 메모리가 별도로 필요하다면 스레드 별로 실행되고 있는 명령어의 위치 또한 다르므로 PC 레지스터도 각각 필요합니다.

 

멀티 프로세스의 예시를 들어주세요.

- 멀티 프로세스는 한 프로세스 내에서 여러 스레드가 있는 경우입니다. 하나의 프로세스가 동시에 여러개의 일을 수행하는 것을 말합니다. 예를 들어, 유튜브에서 동영상이 재생도 되면서 댓글이 저장되는 것이 있습니다.

 

문맥교환은 스레드간에도 일어나나요?

- 네. 프로세스내에서도 스레드간의 문맥교환(Context Switching)이 발생합니다.

 

스레드는 왜 독립적인 스택 메모리를 가지나요?

- 스택영역의 정의부터 정확하게 알아야합니다. 스택영역은 스레드가 프로세스 내에서 함수호출시 전달되는 인자, 함수의 리턴주소등을 저장하기 위한 메모리 영역입니다. 스레드가 하나의 프로세스 내에서 독립적인 기능을 하기 위해서는 독립적인 함수를 호출해야함을 의미하며 이는 독립적인 스택 메모리를 가져야만 가능합니다.

 

프로세스와 스레드의 정의를 정리해주세요.

- 프로세스는 운영체제로 부터 직접 자원을 할당 받는 작업의 단위이며 스레드는 프로세스가 할당 받은 자원을 이용하는 실행의 단위입니다.

 

멀티 프로세스와 멀티 스레드를 비교해주세요.

- 멀티 프로세스와 멀티 프로세스는 동시에 여러작업을 한다는 측면에서 비슷합니다. 멀티 프로세스는 메무리 구분이 필요할때 사용하면되고 멀티스레드는 문맥교환이 자주일어나고 데이터공유가 빈번하다면 사용하면 됩니다.

 

- 문맥교환시 멀티스테드는 스택영역의 내용만 변경되면 되지만 멀티 프로세스의 경우 힙,데이터,코드 영역의 정보까지 바뀌므로 문맥교환의 비용이 멀티프로세스가 높습니다.

 

- 멀티 프로세스는 많은 CPU시간과 메모리공간을 차지하며 하나의 프로세스가 죽더라도 다른 프로세스에 영향을 주지 않습니다.

 

- 멀티 스레드는 적은 메모리 공간을 차지하고 문맥교환 비용이 적으며 자원을 공유하기 때문에 동기화 문제가 발생할 수 있고 하나의 스레드 장애가 여러 스레드의 장애로 이어질 위험이 있습니다.

 

프로세스간 통신은 어떻게 하나요?

- 스레드는 서로의 자원을 공유하고 있기 때문에 스레드간 통신은 별도의 자원을 사용하지 않아도 됩니다. 하지만 프로세스의 경우 데이터를 공유하고 있지 않기 때문에 공유메모리를 사용하는 방법과 메세지전달 방법으로 2가지 방법이 있습니다.

 

- 공유 메모리 : 프로세스들이 주소 공간 일부를 공유하는 것을 의미합니다. 커널이 메모리에 별도의 shared memory를 할당합니다. 프로세스들은 shared memory의 정보를 이용해 서로 데이터를 전달 및 공유 합니다.

 

- 메세지 전달 : 시스템 콜을 이용하여 구현합니다. 시스템 콜이란 커널영역에서 사용하는 명령어들이며 커널을 통해 메세지를 보내고 받습니다. 즉, 프로세스들 사이에 커널이 데이터를 중재하는 것입니다. 예를 들어, pipe , socket , message queue 가 있습니다.

 

2가지 방식의 장단점 역시 존재합니다. 공유메모리를 사용할 경우 간단하지만 메모리를 공유하기 때문에 자원 동기화의 문제가 있을 것이며 메세지를 전달한다면 동기화 문제는 없지만 속도가 느립니다. 

 

멀티 프로세스 , 스레드 환경에서 동기화 문제는 어떻게 해결하나요?

- 먼저 공유된 자원에서 발생하는 동기화문제가 무엇인지 간단하게 알아보겠습니다. 2개의 스레드가 count라는 변수에 접근해서 1씩 증가하는 연산을 한다고 가정해봅시다. count값은 현재 1입니다. 스레드1이 접근해서 count의 값을 읽어옵니다. 다음으로 바로 스레드2가 접근해서 count 값을 읽어옵니다. 스레드1과 스레드2가 각각 count 값을 1을 증가 시켜 2로 만듭니다. 스레드1이 count에 2를 저장합니다. 스레드2가 count에 2를 저장합니다. 원래 같으면 스레드1 과 2를 실행하고 나서 count의 값은 3이 되길 기대했지만 count의 값은 2입니다. 

 

- 해결하는 방법은 뮤텍스 또는 세마포어를 사용합니다. 

 

- 뮤텍스 : 1개의 스레드만 공유자원에 접근가능합니다. 

- 세마포어 : S개의 스레드만이 공유자원에 접근가능합니다. 스레드가 접근할 때 마다 S의 개수를 감소시키며 S가 0이라면 자원에 접근 할 수 없습니다. 

 

- 뮤텍스와 세마포어를 통해 동기화 문제를 해결하는 방법을 알기 전 critical section, entry section , exit section 에 대해서 알아야합니다. 

 

- critical section : 공유할 자원들 즉, 코드 영역에서 여러 스레드들이 접근 할 수 있는 부분을 통제하기 위해서 둘 이상의 프로세스 또는 스레드가 접근하는 것을 막는 코드 부분을 임계영역 (critical section)이라고 합니다. 또한 임계영역내에서 코드들은 원자적으로 실행되어야 합니다. 

 

- entry section : 진입 허가 요청이 완료되어야 임계영역으로 갈수 잇습니다.

 

- exit section : 임계영역 실행후 끝나는 부분

 

- entry section -> critical secition -> exit section 으로 이동합니다.

 

- 뮤텍스를 이용하여 동기화 문제 해결하기 : 뮤텍스는 공유자원 접근하는 프로세스/스레드를 1개로 제한합니다. 

acquire() // entry section

// critical section

release() // exit section


acquire() {
    while(!available); // wait ! 
    available = false;
}

release() {
    available = true;
}

- 세마포어를 이용하여 동기화 문제 해결하기 : 공유자원에 접근하는 프로세스/스레드가 2개이상일 수 있습니다. 

 

wait(S) // entry section

// critical section

signal(S) // exit section

wait(S) {
  while(S<=0); // wait !
  S--;
}

signal(S) {
  S++;
}

 

교착 상태에 대해서 간단히 설명해주세요.

- 둘 이상의 스레드가 다른 스레드가 점유하고 있는 자원을 서로 기다릴때 무한대기에 빠지는 상황입니다. 스레드일수도 있고 프로세스일 수도 있습니다. 이후 스레드로 표현하여 설명하겠습니다.

 

- 교착상태를 데드락이라고 하는데 다음 4가지 모두 성립해야 데드락이 발생합니다. 4가지중 한가지가 아니라 모두 만족해야합니다.

1) 상호 배제 : 한 스레드만 점유 가능

2) 점유 대기 : 한 스레드가 점유한 상태에서 다른 스레드가 기다려야함.

3) 비선점 : 다른 스레드가 점유중인 스레드의 자원을 강제로 선점 불가.

4) 순환대기: 대기중인 스레드들이 사이클을 이뤄야합니다.

 

- 데드락 해결방법 4가지

1) 무시 : 아무조치 안함.

2) 예방 : 4가지중 하나가 성립되지 않도록 미리 예방. 비용이 커서 비추천.

3) 회피 : 자원할당 할때 자원할당 그래프, 은행원 알고리즘을 이용하여 데드락을 회피.

4) 회복 : 데드락이 발생후 탐지하여 회복.

 

% 은행원알고리즘 : 운영체제 입장에서 최소 하나의 프로세스가 필요한 자원은 항상 보유하고 있어야 자원할당 순서에서 안전합니다.

 

 

운영체제는 프로세스를 메모리로 올릴 때 메모리 관리를 어떻게 하나요?

- 프로세스를 통째로 연속된 메모리에 올려놓는 일은 거의 없습니다. 이때까지 편의를 위해 그림으로 그렇게 표현했지만 프로세스들을 무작정 물리 메모리에 순서대로 올리면 많은 문제들이 발생합니다. 예를 들어 한 가지를 설명해보겠습니다.

- 위 그림처럼 프로세스3은 80MB이고 메모리고 90MB의 빈공간이 있지만 할당하지 못합니다. 

 

- 이 처럼 운영체제에서는 효율적으로 프로세스들에게 메모리를 할당해주기 위한 기법이 생기기 시작했습니다. 바로 페이징과 세그멘테이션입니다.

 

 

페이징(Paging)은 무엇인가요?

- 물리 메모리를 동일한 크기로 조각조각 냅니다. 이때 하나의 조각을 페이지라고 합니다. 메모리에 올릴 프로세스도 페이지의 크기만큼 조각내서 물리 메모리에 저장하는 방식입니다. 그렇게 되면 물리 메모리에 연속되서 저장될 필요없이 페이지 단위로 분산되어 저장 가능합니다. 프로세스 입장에서는 자신의 페이지들이 어디있는지 알아야하는데 이를 위해 페이지 테이블이라는 것이 존재합니다. 

 

- 그림에서 보는 것처럼 프로세스당 하나의 페이지 테이블을 가집니다. 하나의 프로세스 내에서 페이지단위로 물리적메모리에 저장되기 때문에 주소를 바인딩하기위해 별도의 테이블이 필요합니다. 물리메모리 주소를 프레임번호라고도 합니다.

 

페이징 기법에서 문제점이 있나요?

- 메모리 내부 단편화 문제가 발생합니다. 프로세스를 페이지 단위로 쪼개다보면 페이지 안에 안쓰는 공간이 남습니다. 예를 들어 100 크기의 프로세스를 30크기의 페이지로 쪼개면 4개의 페이지로 나오고 마지막 페이지는 20이 남습니다. 이러한 페이지를 물리메모리에 할당하게 되면 20이라는 공간은 아무것도 안하고 남아있는 공간이 됩니다.

 

- 외부 단편화 문제는 발생하지 않습니다. 외부단편화는 남아있는 공간은 작은데 그 공간보다 큰 프로세스를 집어넣으려고 할때 발생하는데 프로세스를 페이지 단위로 나누기 때문에 페이지 단위로 무조건 할당됨을 보장하므로 메모리를 할당하지 못해서 나오는 외부단편화 문제는 발생하지 않습니다.

 

세그먼테이션(Segmentation)이 무엇인가요?

- 페이지는 프로세스를 크기단위로 똑같이 나뉘었다면 세그먼테이션은 의미단위로 메모리를 나누는 것을 의미합니다. 프로세스를 코드,데이터,힙,스택으로 기능 단위로 정의한다면 4가지로 조각내어 메모리에 저장합니다.세그먼테이션은 페이징과 마찬가지로 물리적 주소로 변환하기 위한 세그먼테이션테이블을 가지고 있습니다.

 

 

- 만약 논리적 주소가 2 / 200 이라면 어떨까요? 2는 세그먼트 번호를 의미하고 200은 떨어진 거리를 의미합니다. 따라서 세그먼트2번의 주소가 3500 부터 시작하고 3500에서 200떨어진 거리인 3700이 2/200 의 논리적주소가 변경된 물리적 주소입니다.

 

- 이처럼 세그먼트는 모든 크기가 다르기 때문에 항상 시작점과 limit를 같이 표기해야합니다.

 

세그먼테이션의 단점이 있나요?

- 세그먼테이션은 메모리의 내부단편화 문제가 없습니다. 왜냐하면 필요한 만큼 메모리를 정확하게 할당 받기 때문입니다.

- 외부 단편화문제가 존재합니다. 세그먼트가 너무 커서 특정 공간에 할당 못할 수도 있습니다. 세그먼트를 쪼개면 가능하겠지만 이는 불가능합니다.

 

 

가상메모리가 무엇인가요?

- 운영체제는 메모리를 더욱더 효율적으로 사용하기 위해서 도입한 개념입니다. 

 

- 정의 : 프로세스 전체가 메모리에 올라오지 않아도 실행이 가능하도록 하는 것입니다.

 

- 이때까지 메모리에 프로세스 전체가 올라가는 그림이 그려졌습니다. 하지만 가상메모리는 프로세스 전체가 메모리로 올라오지 않습니다. 어떻게 메모리에 전체 프로세스를 올리지 않더라도 프로세스를 실행할 수 있는 것일까요?

 

- 운영체제는 가상메모리 기법을 통해서 프로그램의 논리적 주소 영역에서 필요한 부분만 물리 메모리에 적재하고 직접적으로 필요하지 않은 부분은 디스크(SWAP)에 저장하는 것을 말합니다. 

 

- 페이징 기법을 쓰는 운영체제에서 가상메모리를 사용한다고 가정해봅시다. 당장 사용될 주소 공간을 page단위로 메모리에 적재하는 방법을 요구페이징이라고 합니다. 요구 페이징에서는 특정 페이지에 대해 cpu요청이 들어온 후에 해당 페이지를 메모리에 적재합니다. 당장 실행에 필요한 페이지만을 메모리에 적재하기 때문에 메모리 사용량이 감소하고 프로세스 전체를 메모리에 적재하는 입출력 오버헤드도 감소합니다. 요구페이징 기법에서는 유효/무효 비트를 두어서 각 페이지가 메모리에 존재하는지 표시하게 됩니다.

 

요구페이징에서 CPU가 요청한 메모리에 없고 디스크에 있다면 어떻게 되나요?

1) CPU가 페이지 참조

2) 페이지 테이블을 보니 페이지 상태가 "무효" 상태

3) MMU에서 페이지 폴트 트랩을 발생

4) 디스크에서 메모리로 페이지를 가져온 후 "유효" 상태로 변경

 

이와 같이 요청한 페이지가 없는 경우를 페이지 폴트(Page fault)라고 합니다.

 

페이지 폴트 발생 후 메모리로 페이지를 가져오려는 데 메모리도 부족한 경우라면 어떤 페이지를 교체하나요?

 

- 이를 위한 알고리즘이 존재합니다. 바로 페이지교체 알고리즘입니다. 

- LRU : 가장 오랫동안 사용하지 않은 페이지를 메모리에서 디스크로 방출합니다.

- LFU : 참조 횟수가 가장 적었던 페이지를 메모리에서 디스크로 방출합니다.

 

 

'CS' 카테고리의 다른 글

[언어] JAVA 질문 및 응답  (1) 2022.06.20
[DB] 인덱스  (1) 2022.06.14
[DB] 트랜잭션 질문 및 응답  (0) 2022.06.08
[네트워크] 쿠키,세션 질문 및 응답  (0) 2022.06.08
[네트워크] HTTP 질문 및 응답  (0) 2022.06.08

댓글