Post

CS-운영체제

운영체제에 대한 부분을 질문형으로 작성합니다.

CPU버스트, IO버스트

IO작업이 무엇인가요?
  • 파일을 읽고 쓰거나
  • 네트워크를 통해서 데이터를 주고받거나
  • 입출력 장치와 데이터를 주고받는 것
CPU 버스트가 무엇인가요?

프로세스가 CPU에서 한번에 연속적으로 실행되는 시간을 말합니다.

IO 버스트가 무엇인가요?

프로세스가 IO작업을 요청하고 결과를 받기까지 기다리는 시간을 말합니다.

CPU 바운드 프로세스가 무엇인가요?
  • 프로세스의 IO버스트가 적고 CPU버스트가 많은 것을 말한다.
  • 동영상 편집 프로그램과 머신러닝 프로그램이 그 예이다.
IO바운드 프로세스가 무엇인가요?
  • IO버스트가 많은 프로세스를 말한다.
  • 일반적인 백엔드 API서버가 IO바운드 프로세스의 예이다.
  • DB나 캐시서버에 데이터를 요청하는 것이 IO작업이고 네트워크를 타기 때문에 CPU에서 명령을 처리하는 것보다 오래 걸린다.
듀얼 코어 CPU 에서 동작할 CPU 바운드 프로그램을 구현한다면 몇개의 스레드를 사용하는 것이 좋을까?

CPU 바운드 프로그램은 스레드의 갯수가 너무 많아지면 오히려 컨텍스트 스위칭이 자주 발생해 오버헤드가 늘어납니다. 스레드의 갯수가 코어의 갯수와 가까울수록 하나의 작업을 오랫동안 이어나갈 수 있기 때문에 CPU 코어의 갯수와 같거나, 크게 벗어나지 않는 갯수의 스레드를 사용하는 것이 좋다고 생각한다.

IO 바운드 프로그램은 스레드 몇개로 구현하는 것이 적절할까?

CPU 바운드 프로그램처럼 가이드라인이 있지 않고 컴퓨터의 스펙, 프로그램의 특성에 따라서 적절한 스레드의 수를 찾아야합니다.

만약 API 서버가 Thread per Request방식이라면 스레드를 어떻게 관리해야하는가

백엔드 API서버가 요청이 올때마다 전담 스레드를 할당하는 Thread per Request 방식이라면 API서버에 스레드를 미리 만들어두고 요청이 올 때마다 스레드를 할당하는 것이 좋습니다. 몇개의 스레드를 만들어 놓을지는 여러가지 상황을 고려해서 결정해야합니다.

  • API 서버의 하드웨어 스펙
  • API 애플리케이션의 IO버스트 기준
  • 예상되는 트래픽의 패턴

프로세스

프로세스란? PCB

프로세스가 무엇인가요?

프로세스란 메모리에 올라와서 실행되고 있는 작업의 단위를 말합니다.

프로그램은 무엇인가요?

하드디스크와 같은 저장장치에 저장되어있는 실행코드를 뜻합니다.

프로세스의 상태에 대해서 설명해주세요
  • New: 프로세스가 처음 생성된 상태 말합니다.
  • Ready: 프로세스가 CPU를 할당받기를 기다리는 상태
  • Running: 프로세스가 CPU를 할당받고 명령을 수행중인 상태
  • Waiting: 프로세스가 어떠한 이벤트가 발생하기를 기다리는 상태. CPU를 할당해도 당장 명령을 수행할 수 없는 상태입니다. IO작업을 기다리거나 시스템 자원을 기다리는 경우입니다.
  • Terminated: 프로세스가 실행을 마친 상태입니다. 그래도 아직 완전히 프로세스가 제거된 상태는 아닙니다.
PCB에 대해서 설명해주세요.

PCB는 운영체제가 프로세스를 관리하기 위해 프로세스별로 가지고 있는 정보입니다.

프로세스의 상태와 프로세스 아이디, 프로그램 카운터, 레지스터등의 정보를 담고 있습니다.

왜 PCB를 사용하나요?

프로세스가 여러 개일 때 프로세스를 스케줄링을 통해서 관리합니다. 어떤 프로세스인지 알아야 관리가 가능합니다. 그래서 프로세스의 정보를 담고 있는 PCB가 필요합니다.

  • CPU를 점유한 시간, 스케줄링 정보가 담겨있어 운영체제가 최적의 스케줄링 알고리즘을 적용할 수 있도록 도와준다.
  • 프로세스의 코드, 데이터, 스택영역의 메모리 위치와 한계가 명시되어 있어 메모리 관리를 용이하게 한다.
  • 컨텍스트 스위칭 시 CPU의 레지스터 값을 저장하고 복구할 수 있도록 해준다.
  • 프로세스의 접근 권한등의 정보가 있어 자원에 대한 보안 접근제어가 가능하게 해준다.
PCB는 어떻게 관리되나요?

PCB는 일반적으로 이중 연결리스트 방식으로 관리됩니다. 새로운 프로세스가 생성될 때마다 새로운 PCB가 PCB List Head에 붙고, 프로세스가 종료되면 연결리스트에서 unlink시키는 방식으로 관리됩니다.

컨텍스트 스위칭

Context Switching이란 무엇인가요?

프로세스가 실행되다가 CPU를 다른 프로세스로 넘겨주는 과정을 말합니다. 운영체제가 CPU를 내어주는 프로세스의 상태를 PCB에 저장하고, CPU를 새롭게 얻어오는 프로세스의 상태를 PCB를 통해 읽어옵니다.

인터럽트가 발생하면 항상 Context Switching이 일어나나요?

시스템 콜이나 인터럽트가 발생한다고 해서 무조건 Context Switching이 일어나는 것은 아닙니다. 다른 프로세스에 프로세서가 넘어가야 Context Switching 입니다. 인터럽트가 발생해도 기존에 수행하던 프로세스를 이어서 수행하는 경우도 있습니다.

Context Switching은 언제 발생하나요?
  • 인터럽트가 발생하거나,
  • CPU 사용시간을 모두 소모했거나,
  • 입출력을 위해 대기해야 하는 경우 발생합니다.
Context Switching은 무엇에 의해서 통제되나요?

OS 커널에 의해서 통제됩니다.

프로세스 컨텍스트 스위칭과 스레드 컨텍스트 스위칭에 대해서 설명해주세요.

다른 프로세스들끼리 스위칭을 하는것을 Process Context Switching이라고 하고, 같은 프로세스의 스레드들끼리의 스위칭을 Thread Context Switching이라고 합니다.

둘의 공통점은

  • 커널모드에서 실행된다. 컨텍스트 스위칭을 할 때는 통제권이 커널로 넘어갑니다.
  • CPU의 레지스터 상태를 교체한다.

둘의 차이점은

  • 스레드 컨텍스트 스위칭은 같은 프로세스에 속하기 때문에 주소관련 처리를 해줄 필요가 없다. 프로세스의 메모리 영역을 공유하기 때문이다.
  • 다른 프로세스에 속하는 스레드들끼리 컨텍스트 스위칭이 일어났을 때는 메모리 주소 체계가 다르기 때문에 메모리 주소관련 처리를 추가로 수행해주어야한다. MMU도 새로운 프로세스의 주소체계를 바라볼 수 있도록 수정해주어야하고, 가상 메모리 주소와 실제 물리메모리 주소의 매핑정보가 담긴 TLB도 비워주어야한다.
프로세스 컨텍스트 스위칭의 과정에 대해서 설명해주세요

프로세스 컨텍스트 스위칭은 서로 다른 프로세스에 속하는 스레드들끼리 스위칭이 일어나는 것을 말합니다. 기존에 수행되던 쓰레드의 CPU상태를 저장하고, 새로운 스레드의 CPU상태를 로딩합니다. 이 과정에서 MMU가 새로운 프로세스의 메모리를 바라보도록 수정되고, TLB를 완전히 비워줍니다. 이 작업을 해주지 않으면 이전에 수행되던 프로세스의 메모리 영역에 접근하게 됩니다. 이 과정을 마치면 컨텍스트 스위칭이 끝납니다.

스레드 컨텍스트 스위칭이 프로세스 컨텍스트 스위칭 보다 빠른가요?

네. 프로세스 컨텍스트 스위칭에서는 메모리 관련 처리를 추가로 해주어야하기 때문에 스레드 컨텍스트 스위칭이 더 빠릅니다.

컨텍스트 스위칭이 미치는 간접적인 영향은?

캐시오염(cache pollution)이 있습니다. 캐시는 CPU옆에 붙어서 자주 사용하는 데이터들을 담아두어 메모리까지 가지않고도 데이터를 빠르게 가져올 수 있도록 도와주는 역할을 하는데, 프로세스 컨텍스트 스위칭이 일어나면 이전에 수행되던 프로세스가 사용하던 내용이 캐시에 담겨져 있기 때문에 필요로 하는 정보가 없을 확률이 큽니다. 그래서 메모리에 접근해야하기 때문에 성능에 안좋은 영향을 끼치기도 합니다.

애플리케이션 관점에서 컨텍스트 스위칭이란?

애플리케이션 관점에서는 순수한 오버헤드입니다. 프로그램의 동작과는 상관없이 CPU를 잡아먹는 간접 비용입니다.

컨텍스트 스위칭에서 CPU의 레지스터 상태를 교체하는 이유가 무엇인가요?

CPU의 레지스터에는 프로세스를 수행하기 위한 데이터들이 담겨있습니다. 프로세스의 스위칭이 일어나서 프로세스가 다시 수행될 때 상태정보를 담고 있어야 하기 때문이다.

프로세스 스케줄링

멀티 프로그래밍의 목적이 무엇인가요?

CPU를 최대한 활용하기 위해서 몇몇 프로세스를 항상 실행시키는 것 입니다.

Time Sharing의 목적이 무엇인가요?

프로세스간에 CPU를 빠르게 전환해서 사용자가 각 프로그램이 실행되는 동안 서로 상호작용할 수 있도록 하는 것 입니다.

프로세스 스케줄링이 무엇인가요?

프로세스 스케줄링이란 CPU를 어떤 프로세스에 할당할 것인지 결정하는 것을 말합니다.

프로세스를 스케줄링하기 위한 세가지의 큐에 대해 설명해주세요.

프로세스를 스케줄링 하기 위한 큐에는 Job Queue, Ready Queue, Device Queue가 있습니다.

  • Job Queue는 하드디스크에 있는 프로그램이 실행되기 위해 메인 메모리의 할당을 기다리는 큐
  • Ready Queue는 현재 메모리 내에 있고, CPU를 할당받기를 기다리는 프로세스의 집합,
  • Device Queue는 Device I/O작업을 대기하고 있는 프로세스의 집합입니다.
스케줄러의 종류인 장기, 중기, 단기 스케줄러에 대해 설명해주세요

image

사용할 수 있는 메모리는 한정되어 있는데 프로세스들이 한꺼번에 메모리에 올라올 경우 디스크에 임시로 저장됩니다. 장기스케줄러는 디스크에 있는 프로세스 중에서 어떤 프로세스를 Ready Queue로 보낼지 결정하는 스케줄러입니다. 디스크와 메모리 사이의 스케줄링을 담당하고 실행중인 프로세스의 수를 제어한다는 점이 특징입니다.

단기 스케줄러는 메모리에 올라와 있는 프로세스 중 어떤 프로세스에게 CPU를 할당할지를 결정합니다. 메모리와 CPU사이의 스케줄링 담당하여 Ready Queue에 있는 프로세스중 어떤 프로세스에 CPU를 할당할지 결정합니다.

중기 스케줄러는 여유공간의 마련을 위해 어떤 프로세스를 메모리에서 디스크로 swap out 할지 결정하는 스케줄러입니다. 시스템의 메모리에 너무 많은 프로그램이 올라오는 것을 제어하기 위해서 사용합니다. 이 스케줄러도 실행중인 프로세스의 수를 제어한다는 점이 특징입니다.

어떤 경우에 프로세스를 메모리에서 디스크로 swap out하나요?

ready 상태에서 계속 CPU를 점유하지 못하거나 sleep 상태에서 ready 상태로 넘어가지 못하는 프로세스는 실행도 잘 되지 못하면서 메모리에서 자리만 차지하게 됩니다. 이때 세컨더리 스토리지로 swap out 됩니다.

New 상태에서도 suspended ready상태로 갈 수 있나요?

원래는 메모리를 할당받아서 ready 상태가 되어야하는데 여러가지 문제로 인해서 메모리 할당을 받지 못하면 suspended ready 상태로 갈 수 있습니다.

선점/비선점 스케줄링에 대해서 설명해주세요.
  • 선점(preemptive)은 OS가 CPU의 사용권을 선점할 수 있는 경우를 말합니다. 현재 수행하고 있는 작업이 있다고 하더라도 강제로 CPU를 회수할 수 있습니다.
  • 비선점(Non-Preemptive)는 프로세스가 종료되거나 I/O이벤트가 발생하기 전까지 실행을 보장하는 것을 의미합니다.
프로세스의 suspended상태에 대해 설명해주세요.

중기 스케줄러에 의해 프로세스가 메모리에서 디스크로 swap out되면 suspended 상태가 됩니다. 외부적인 이유로 프로세스의 수행이 정지된 상태를 말합니다. blocked된 상태는 Device의 I/O작업을 기다리는 상태이기 때문에 스스로 ready상태로 돌아갈 수 있지만 이 suspended 상태는 외부적인 이유로 중지되었기 때문에 스스로 돌아갈 수 없습니다.

CPU 스케줄링 알고리즘에 대해 설명해주세요.

Ready Queue에 있는 프로세스 중 어떤 프로세스에 CPU를 할당할지 결정하는 알고리즘을 말합니다. FCFS, SJF, SRTF, Priority-Scheduling, RR 등의 알고리즘이 있습니다.

FCFS는 먼저 온 작업을 먼저 처리해주는 방식입니다. 소요시간이 긴 프로세스가 먼저 도달하게 되면 효율성이 낮아집니다.

SJF는 다른 프로세스가 먼저 도착했어도 CPU사용시간이 짧은 프로세스에게 CPU를 우선적으로 할당하는 방법입니다. 효율성을 추구하긴 하지만 수행시간이 긴 프로세스의경우 우선순위가 계속 뒤로 밀려서 영원히 CPU를 할당받지 못할 수도 있는 starvation문제가 발생할 수도 있습니다.

Priority Scheduling은 프로세스에 우선순위를 주고 우선순위가 높은 프로세스를 먼저 수행하는 것입니다. 이 또한 starvation문제가 발생할 수도있고, 이를 우선순위가 낮은 프로세스라도 기다리는 시간이 길어질수록 높은 우선순위를 주는 aging이라는 방식을 통해 해결할 수 있습니다.

Round Robin은 각 프로세스가 time quantum이라는 동일한 크기의 할당시간을 가지고 할당시간이 끝나면 다음 프로세스에게 CPU의 할당을 넘기게 됩니다. time quantum이 너무 길어지면 FCFS알고리즘과 다를 바가 없어지고, 너무 짧으면 context switching이 너무 길어져 그만큼 오버헤드가 많이 소모됩니다.

Reentrant에 대해 설명해주세요

어떤 함수가 Reentrant하다는 것은 여러 스레드가 동시에 접근해도 항상 같은 실행 결과를 보장한다는 의미입니다.

프로세스 관리(Process Management)

fork 시스템 콜에 대해서 설명해주세요.

fork를 이용하면 부모를 그대로 복사해서 현재 프로세스와 pid만 다른 새로운 프로세스를 생성합니다.

Copy-On-Write에 대해 설명해주세요

리소스가 복제되었지만 수정되지 않은 경우 새로운 리소스를 만들 필요 없이 복사본과 원본이 같은 리소스를 공유하다가, 복사본이 수정되었을 때만 새 리소스를 만드는 방법입니다. 쓰기 작업을 하기 전까지 copy작업을 지연시켜서 효율성을 높여줍니다.

copy-on-write의 단점에 대해서 설명해주세요.

많은 양의 RAM을 사용하고 copy하는데 시간이 오래 걸린다는 단점이 있습니다.

그러한 단점을 어떻게 해결하나요?

프로세스의 전체 주소공간이 아니라 페이지 테이블을 복사하는 것으로 해결할 수 있습니다.

exec 시스템 콜에 대해 설명해주세요.

exec 시스템 콜은 어떤 프로그램을 완전히 새로운 프로세스로 태어나도록 하는 역할을 합니다. 프로세스가 exec 시스템 콜을 통해 다른 프로그램을 수행할 수 있도록 해줍니다.

wait 시스템 콜에 대해 설명해주세요.

wait 시스템콜은 부모프로세스가 자식프로세스가 종료 될때까지 대기하도록 하는 시스템 콜입니다. 자식 프로세스가 종료되면 커널이 부모 프로세스를 깨워 Ready 상태로 만듭니다.

자발적 종료에 대해서 설명해주세요

프로세스가 마지막 명령문을 수행하고 운영체제에 exit명령어를 통해서 이에 대해 알려주는 것을 말합니다. 그러면 프로세스의 각종 자원들이 운영체제에 반납됩니다.

비 자발적 종료에 대해서 알려주세요

부모프로세스가 자식프로세스를 강제로 종료시키는 것을 말합니다. 자식이 할당된 자원의 한계치를 넘어서거나 자식에게 할당된 작업이 더 이상 필요하지 않거나, 부모 프로세스가 종료되는 경우에 발생합니다. 운영체제는 기본적으로 부모 프로세스가 종료되는 경우 자식이 계속 수행되는 것을 허용하지 않기 때문에 자식 프로세스를 단계적으로 종료시켜나갑니다.

하지만 프로세스의 비 정상적인 종료로 인해서 좀피 프로세스나 고아 프로세스같은 유형의 프로세스가 존재할 수 있습니다.

좀비프로세스에 대해 설명해주세요.

실행이 끝났지만 아직 프로세스의 정보가 메모리에 남아있는 프로세스를 말합니다. 프로세스가 종료되었지만 버그나 에러로 인해서 해당 프로세스의 부모가 아직 wait를 통해 정보를 수집하지 못한 상태입니다. 모든 프로세스는 잠깐 좀비프로세스 상태로 존재할 수 있습니다.

고아 프로세스에 대해 설명해주세요.

부모가 wait를 호출하지 않고 종료되었을 때 자식 프로세스를 말합니다. 즉 부모는 종료되었지만 자식은 아직 종료되지 못한 상태입니다. 이런 경우에는 init process가 고아 프로세스의 부모가 되고 주기적으로 wait를 호출해서 고아 프로세스의 종료 상태(exit status)를 수집하게 됩니다

IPC

IPC란 무엇인가요?

프로세스는 독립적인 메모리 공간을 가지고 있기 때문에 서로 영향을 끼치지 않는데 이런 프로세스들 사이에서도 메모리를 공유해야하는 경우가 있습니다. 이를 가능하게 해주는 것이 IPC이고, 프로세스가 커널이 제공하는 IPC설비를 이용해서 프로세스간 통신을 할 수 있습니다.

IPC 설비 종류에 대해서 설명해주세요.

IPC 설비 종류에는 PIPE, Named PIPE, Message Queue, Shared Memory가 있습니다.

먼저 PIPE는 두개의 프로세스를 연결하는데 사용됩니다. 한쪽의 프로세스는 쓰기만하고 다른 한쪽의 프로세스는 읽기만 할때 유용한 통신으로, 한쪽 방향으로 통신이 가능한 반 이중 통신이라고 합니다. 매우 간단하게 사용할 수 있기 때문에 단순한 데이터의 흐름일 때는 파이프를 사용하는 것이 좋습니다. 하지만 양방향 통신을 위해서는 두개의 파이프를 구현해야한다는 점이 단점입니다.

익명파이프는 통신상대를 명확히 알 수 있는 경우, 즉 부모 자식관계의 프로세스들사이에서 사용하지만 Named PIPE는 전혀 모르는 상태의 프로세스들 사이의 통신에도 사용할 수 있습니다. 익명 파이프와 마찬가지로 양방향 통신을 하려면 2개의 파이프를 구현해야한다는 단점이 있습니다.

Message Queue는 입출력방식은 Named PIPE와 동일하지만 다른 점은 파이프처럼 데이터의 흐름이 아니라 메모리 공간이라는 점입니다.

Shared Memory는 데이터 자체를 공유하도록 지원해주는 설비입니다. 프로세스가 공유메모리의 할당을 요청하면 커널이 해당 프로세스에 메모리 공간을 할당해주고 이후 모든 프로세스가 해당 메모리 영역에 접근할 수 있게 됩니다. 중개자 없이 바로 메모리에 접근할 수 있으므로 IPC중에서 가장 빠르게 동작합니다.

메시지 패싱(Message Passing, 메세지 큐 이용)에 대해 설명해주세요.

메시지 패싱은 커널의 메세지 큐를 통해 메세지를 주고받는 것을 말합니다. Context Switch가 발생하기 때문에 속도가 느리지만 커널이 기본 기능을 제공하기 때문에 공유 메모리 방식보다 구현이 쉽습니다. 메시지 패싱에서 Direct/Indirect Communication 이라는 두 가지 방식으로 나뉩니다.

Direct Communication에 대해 설명해주세요

Direct Communication은 통신하려는 프로세스의 이름을 명시적으로 표시하는 방법입니다. 통신하고자 하는 모든 프로세스에 링크가 자동으로 생성되기 때문에 각각의 프로세스들은 서로의 이름만 알면됩니다.

하지만 모든 프로세스의 이름을 알아야하고 모듈성이 좋지 않다는 단점이 있습니다. 모듈성이란 구성요소의 일부분을 변경할 때 전체에 영향을 미치지 않도록 설계되어있는 것을 말하는데 Direct Commucation은 어떤 프로세스의 이름을 변경하면 연결되어있는 모든 Sender와 Receiver의 정보를 바꾸어야하기 때문입니다.

Indirect Communication에 대해 설명해주세요.

Indirect Communication은 메세지를 프로세스가 직접 전달하는 것이 아니라 메일박스를 통해서 전달하는 것을 말합니다.

메세지 큐는 단방향 통신인가요?

메세지 큐는 프로세스간 양방향통신을 할 수 있습니다. 심지어 자기자신에게도 보내고 받을 수 있습니다.

언제 메시지 큐를 사용하나요?

메세지 큐는 소비자가 어느 시점에 큐에 있는 데이터를 가져가서 소비하는지는 보장하는 것이 아니라 언젠가는 소비 될것이라고 맡겨두는 것이기 때문에 실패하면 치명적인 핵심작업 보다는 애플리케이션의 부가적인 작업에서 사용하는 것이 좋다고 생각한다.

메세지 큐의 장점에 대해서 설명해주세요
  • 메세지 큐는 생산된 메세지에 대한 동기화 처리를 진행하지 않고 큐에 넣어두어 비동기로 처리할 수 있습니다.
  • 생산자 서비스와 소비자 서비스가 독립적으로 행동하게되어 비즈니스 결합도가 낮아집니다.

스레드

스레드란

스레드가 무엇인가요?

스레드는 CPU수행의 기본단위 입니다. Thread Id, PC, Register Set, Stack Space로 구성되고 각각의 스레드가 자신의 레지스터 상태와 스택을 가집니다. 하지만 Code, Data 영역이나 다른 운영체제 자원들은 스레드끼리 공유합니다.

싱글 스레드와 멀티 스레드에 대해 설명해주세요.

한 프로세스가 한번에 하나의 스레드를 이용하여 한 작업만 수행하는 것을 싱글 스레드라고 하고, 한 프로세스가 여러 스레드를 이용하여 여러 작업을 동시에 수행하는 것을 멀티스레드 라고 합니다.

멀티 프로세스 대신 멀티 스레드를 사용해야하는 이유를 설명해주세요.
  1. Process Context Switching 비용이 Thread Context Switching 보다 많이듭니다. Process Context Switching은 메모리 주소관련 작업을 추가로 처리해주어야 하기 때문입니다.
  2. 두 프로세스가 하나의 데이터를 공유하려면 메시지 패싱이나 공유메모리 또는 파이프를 사용해야하는데 이것은 효율도 떨어지고 개발자가 구현하고 관리하기도 어렵기 때문입니다.
멀티스레딩의 장점에 대해서 설명해주세요.
  1. 응답성이 좋습니다. 싱글 스레드인경우 작업이 끝나기 전까지 사용자에게 응답하지 않지만 멀티스레드인 경우 작업을 분리해서 실행하기 때문에 실시간으로 사용자에게 응답할 수 있습니다.
  2. 자원공유에 좋습니다. 프로세스는 오직 공유메모리나 메시지 패싱을 통해서 자원을 공유할 수 있지만 스레드는 자신이 속한 프로세스 내의 스레드들과 메모리와 자원을 공유하여 효율적으로 사용할 수 있습니다.
  3. 프로세스를 생성하는 비용보다 스레드를 새로 생성하는 것이 훨씬 싸고 Context Switching의 오버헤드도 스레드가 더 경제적입니다.
  4. 싱글 스레드인 경우 한 프로세스는 오직 한 프로세서에서만 수행가능하지만 멀티 스레드인경우 한 프로세스를 여러 프로세서에서 수행할 수 있습니다.
멀티스레딩의 단점에 대해서 설명해주세요.

같은 프로세스 내의 스레드끼리 자원을 공유하기 때문에 동시성문제를 고려해야합니다.

유저레벨 스레드와 커널레벨 스레드에 대해서 설명해주세요.

유저 스레드는 커널 위에서 커널의 도움 없이 유저 수준의 스레드 라이브러리가 관리하는 스레드이고 커널 스레드는 커널이 지원하는 스레드 입니다.

유저 스레드와 커널 스레드의 장단점에 대해 설명해주세요.

커널 스레드를 사용하면 안정적이지만 유저모드에서 커널모드로 계속 바꿔줘야 하기 때문에 성능이 저하됩니다. 반대로 유저모드를 사용하면 안정성은 떨어지지만 성능이 저하되지는 않습니다.

Race Condition

Race Condition이 무엇인가요?

여러 프로세스와 스레드가 동시에 같은 데이터에 접근할 때 타이밍이나 접근 순서에 따라 결과가 달라질 수 있는 상황을 말한다.

어떤 경우에 Race condition이 발생하나요?
  1. 커널모드로 코드를 수행하던 중 인터럽트가 발생하는 경우.
    • 프로세스는 서로 할당받은 메모리만 사용하지만 커널은 서로 다른 프로세스 끼리도 공유하기 때문에 발생한다.
    • 작럽업 중 인터트가 발생하더라도 작업이 끝나고 인터럽트를 처리하도록 처리순서를 부여하면 해결할 수 있다.
  2. 프로세스가 시스템 콜을 호출해서 커널모드로 수행중일 때 컨텍스트 스위칭이 발생하는 경우.
    • 사용자 프로세스가 시스템콜을 호출하여 커널안에 존재하는 변수를 수정했을 때 CPU시간이 만료되어 컨텍스트 스위칭이 일어나고 다른 프로세스가 이전 프로세스와 동일한 시스템콜을 호출하여 동일한 변수에 접근할 때 문제가 발생하는 케이스이다.
    • 커널모드에 있을 때는 CPU를 빼앗지 않는 방법으로 해결할 수 있다.
  3. 멀티 프로세서에서 공유 메모리의 커널 데이터의 접근하는 경우.
    • 커널 내부의 변수에 접근할 때 lock, semaphore를 걸어 접근할 수 있는 프로세스의 수를 제어하는 방법으로 해결할 수 있다.
Critical Section이 무엇인가요?

공유 자원을 사용하는 코드 영역을 Critical Section이라고 합니다.

Critical Section으로 인해 발생하는 문제를 해결하려면 어떤 조건을 만족해야하나요?
  1. Mutual Exclusive(상호배제) : 이미 한 프로세스가 Critical Section에서 작업 중이면 다른 프로세스는 Critical Section에서 작업할 수 없다.
  2. Progress(진행): Critical Section에서 작업중인 프로세스가 없다면 Critical Section에 진입하고자 하는 프로세스가 있는 경우 진입할 수 있어야한다.
  3. Bounded Waiting (한정 대기): 프로세스가 Critical Section에 진입하고자 할 때 무한정 대기하도록 해서는 안된다.

이 세가지의 조건을 만족해야 Critical Section의 해결책이라고 말할 수 있습니다.

Java에서 Critical Section 이슈가 있는 사례를 말해보세요

자주 쓰이는 자바 클래스 중에 SimpleDateFormat 이라는 클래스는 동기화 되지 않은 것이 있습니다.

Mutex Lock에 대해서 설명해주세요.

Mutex는 공유자원에 동시에 접근하는 것을 막기 위해서 Critical Section에 진입하는 프로세스가 Lock을 획득하고, 나올 때 Lock을 방출해서 동시에 접근하지 않도록 하는 방법입니다. lock이 하나만 존재할 수 있는 락킹 메커니즘을 따릅니다.

Mutex의 단점은 무엇인가요?

Critical Secion을 이미 어떤 프로세스가 사용 중인 경우 다른 프로세스들은 Critical Section에 진입하려 시도하기 때문에 cpu를 낭비하게 됩니다.

Spin Lock에 대해서 설명해주세요

Spin Lock은 프로세스가 Lock이 반환됐는지 지속적으로 확인하는 방법입니다. Critical Section에 진입을 위한 대기시간이 짧을 때, Context Switching하는 비용보다 기다리는 비용이 더 효율적인 상황을 위해서 고안된 개념입니다.

SpinLock의 단점

Lock을 확인하는 동안 CPU자원을 계속 낭비한다는 단점이 있습니다.

Semaphore에 대해서 설명해주세요

카운터를 사용해서 동시에 자원에 접근할 수 있는 프로세스의 수를 제한하는 방법입니다.

세마포어에는 Counting Semaphore, Binary Semaphore 두종류가 있습니다.

  1. Counting Semaphore: 카운터 값의 범위가 0이상으로 제한이 없고, 남아있는 자원의 수를 세는데 사용됩니다.
  2. Binary Semaphore는 카운터 값이 오직 0과 1입니다. Mutex Lock과 동일한 역할을 합니다.
세마포어를 언제 활용하나요?

동기화를 시켜주거나, 작업의 순서를 정해주어야할 때 사용합니다.

Binary Semaphore와 Mutex Lock의 차이점이 무엇인가요?

첫번째로 매커니즘이 다릅니다. 바이너리 세마포어는 시그널링 매커니즘에 기반한 기능이고 뮤텍스는 잠금 매커니즘에 기반한 기능입니다. 그리고 바이너리 세마포어는 꼭 세마포어를 얻은 쓰레드가 아니더라도 다른 우선순위가 높은 쓰레드가 시그널을 통해서 잠금을 해제할 수 있지만 뮤텍스는 잠금을 건 쓰레드만이 해제할 수 있습니다. 바이너리 세마포어는 소유권이 없지만 뮤텍스는 소유자만 잠금을 해제할 수 있기 때문입니다.

여기서 오는 속도의 차이가 있기 때문에 두 가지 중에 선택해야한다면 인스턴스의 수가 많을 때는 바이너리 세마포어를 사용하고 인스턴스가 하나라면 뮤텍스를 사용하는 것이 좋다고 생각합니다.

Block & Wakeup 방식에 대해서 설명해주세요

세마포어를 얻지 못한 프로세스가 무한정 대기하는 Busy Waiting 문제를 해결하기 위해서 Critical Section 진입을 실패한 프로세스를 기다리게 하지 않고 Block 시킨 후 Critical Section 자리가 나면 다시 깨워주는 방법입니다.

하지만 일반적으로 Busy Waiting이 비 효율적이지만, Critical Section이 매우 짧은 경우 Block & Wakeup 방식의 오버헤드가 더 커질수도 있습니다.

메모리 관리

논리적주소와 물리적 주소에 대해서 설명해주세요

프로세스의 주소는 논리적 주소와 물리적 주소로 나뉩니다. 논리적 주소는 CPU가 생성하는 주소이고 프로세스마다 독립적으로 가지는 주소공간이기 때문에 프로세스 내부에서 사용하고 각 프로세스마다 0부터 시작합니다.

물리적 주소는 프로그램이 실행되기 위해 실제로 RAM에 올라가는 주소를 말합니다.

Address Binding이 무엇인가요?

Address Binding은 어떤 프로그램이 메모리의 어느 위치에 올라갈지 결정하는 것을 말한다. 바인딩 되는 시점에 따라서 컴파일 타임, 로드 타임, 런타임으로 나뉩니다.

컴파일 타임 Address binding에 대해서 알려주세요.

프로세스의 물리적주소가 컴파일 타임에 결정되는 것을 말합니다. 프로세스가 메모리의 어디에 들어갈지 미리 알고 있다면 컴파일러가 절대주소, 고정된 주소를 생성합니다. 따라서 위치가 변경된다면 재컴파일을 해주어야합니다. 컴파일 타임의 주소는 할당한 논리적 주소와 물리적 주소가 동일하다는 특징이 있습니다.

하지만 컴파일 타임의 주소 할당은 주소가 고정되어 있기 때문에 메모리 상에 빈 공간이 많이 발생할 수 있어 비효율적이고, 로드하려는 위치에 이미 다른 프로세스가 존재할 수도 있습니다.

로드 타임 Address binding에 대해서 알려주세요.

로드타임 주소는 로더가 프로세스를 메모리에 로드하는 시점에 물리적주소를 결정하는 방법입니다. 따라서 로드 타임 주소 할당은 논리적 주소와 물리적주소가 다릅니다.

하지만 프로세스 내에 실제 메모리 주소를 참조하는 명령어들이 많아서 이 주소를 하나하나 바꾸어 주어야하기 때문에 로딩할 때 시간이 오래 걸릴 수 있다는 단점이 있습니다.

컴파일 타임과 로드 타임 address binding은 잘 사용되지 않습니다.

런타임 address binding에 대해서 설명해주세요.

프로세스가 실행 될 때 메모리주소를 바꾸는 방법입니다. 런타임에 물리적 주소가 결정되고 실행 도중에 주소가 바뀔 수 있습니다. CPU가 주소를 참조할 때마다 address mapping table을 이용해서 binding을 점검합니다.

런타임 주소할당은 MMU(Memory Management Unit)을 이용해서 논리적 주소를 물리적 주소로 바꾸어줍니다. 프로세스가 CPU에서 수행되면서 생성해내는 모든 주소값에 대해서 base register 값을 더해서 물리적 주소를 생성하는 방식입니다. base register는 하나이기 때문에 여러 프로세스끼리 공유할 수 있습니다.

Limit Register는 논리적 주소의 범위이고, base register는 접근할 수 있는 물리적 주소의 최솟값을 나타냅니다.

주의해야할 점은 커널모드일 경우에는 MMU가 물리적인 주소로 변환하지 않고 논리적 주소를 그대로 사용하기 때문에 커널모드인지 체크하는 과정도 담겨있습니다.

Swapping이 무엇인가요?

프로세스를 메모리에서 디스크로 내보내고 들여보내는 것을 Swapping이라고 합니디. 메모리의 크기는 크지 않기 때문에 메모리에 있던 프로세스를 임시로 디스크에 보냈다가 다시 가져오는 상황이 발생하곤 합니다. 이때 디스크로 내보내는 것을 swap out, 메모리로 가져오는 것을 swap in 이라고 합니다. 일반적으로 중기 스케줄러에 의해서 swap out 시킬 프로세스가 결정되고 우선순위가 낮은 프로세스부터 swap out 됩니다.

Contiguous Allocation이 무엇인가요?

Contiguous Allocation은 말 그대로, 각 프로세스들이 연속적인 메모리 공간을 차지하게 되는 것을 말합니다.

고정분할 방식에 대해서 설명해주세요.
  • 프로세스의 크기와 상관없이 메모리를 같은 크기로 나누는 것입니다.
  • 메모리를 일정한 크기로 나누어 관리하기 때문에 메모리 관리가 수월합니다.
  • 단, 일정하게 나누어진 공간보다 작은 프로세스가 올라올 경우 메모리 낭비가 발생한다는 단점이 있습니다.
가변분할 방식에 대해서 설명해주세요.
  • 가변분할 방식은 프로세스의 크기에 따라 메모리를 나누는 것입니다.
  • 가변 분할 방식에서는 프로세스를 한 덩어리로 처리하여 하나의 프로세스가 연속된 공간에 배치됩니다.
  • 가변 분할 방식은 메모리 관리가 복잡하다. 메모리 통합 등 부가적인 작업이 필요하다.
Block과 Hole에 대해서 설명해주세요.

Contiguous Allocation에서 메모리를 분할하는 단위를 Block이라고 하고 프로세스가 사용할 수 있는 메모리 Block을 Hole이라고 합니다.

가변분할 방식에서 새로운 프로세스를 할당할 메모리를 찾는 방법에 대해서 설명해주세요.

First-Fit, Best-Fit, Worst-Fit 세가지 방법이 있습니다.

  • First-Fit은 크기가 n이상인 Hole중 최초로 발견한 Hole에 할당하는 방법입니다.
  • Best-Fit은 크기가 n이상인 Hole중 가장 작은 Hole을 찾아 할당하는 방법입니다. Hole의 크기가 정렬되어 있지 않다면 모든 Hole을 탐색해야합니다.
  • Worst-fit은 가장 큰 Hole에 할당하는 방법입니다.
Fragmentation이 무엇인가요?

Fragmentation 이란 메모리에 프로세스가 적재되고 제거되는 일이 반복되면 프로세스들이 차지하는 메모리 틈 사이에 사용하지 못할 만큼의 작은 공간들이 늘어나는 현상을 말합니다. 외부 단편화(external fragmentation)과 내부 단편화(internal fragmentation)으로 나뉩니다.

외부 단편화가 무엇인가요?

외부 단편화는 총 남아있는 공간을 계산 했을 때 프로세스가 들어갈 수 있음에도 불구하고 공간이 연속하지 않아 사용할 수 없는 경우를 말합니다.

내부 단편화가 무엇인가요?

프로세스가 사용하는 메모리 공간보다 분할된 공간이 더 커서 메모리가 남는 경우를 말합니다.

외부 단편화를 어떻게 해결하나요?

외부 단편화를 해결할 수 있는 방법으로는 Compaction(압축)이 있습니다. 프로세스가 사용하는 공간들을 한쪽으로 몰아서 공간을 확보하는 작업입니다. 하지만 비용이 많이드는 작업이라 효율적이지는 않습니다.

페이징에 대해서 설명해주세요

페이징은 연속적으로 메모리를 할당하는 것이 아니라 블록단위로 메모리를 할당하는 방식입니다. 이 방법을 사용하면 외부 단편화의 압축작업의 비효율성을 해결할 수 있습니다.

메모리는 프레임, 프로세스는 페이지라 불리는 고정 크기의 블록으로 분리됩니다. 한 프로세스가 사용하는 공간은 여러 페이지로 나뉘어 관리되고, 각각의 페이지는 순서와 관계없이 메모리의 프레임에 매핑되어 저장됩니다.

프로세스가 순서대로 메모리에 저장되어 있지 않기 때문에 프로세스를 실행하기 위해서는 페이지가 어느 프레임에 들어있는지를 알아야 합니다. 이에 대한 정보가 페이지 테이블에 저장되어 있고 이것을 사용하여 논리적 주소를 물리적 주소로 변경합니다.

페이징의 장점은 무엇인가요?

페이지들이 연속할 필요가 없기 때문에 외부단편화를 해결할 수 있고 할당과 해제가 빠르다는 장점이 있습니다.

페이징의 단점은 무엇인가요?

페이징의 단점은 내부단편화를 해결하지 못하고 페이지 테이블을 위한 메모리가 추가로 소모된다는 점이 단점입니다. 그리고 페이지 테이블이 메모리에 상주하기 때문에 2번의 메모리 접근이 필요해져 속도가 느려집니다.

TLB(Translation Look-aside Buffer)에 대해서 설명해주세요

image

  • 가상메모리 주소를 물리적인 주소로 변환하는 속도를 높이기 위해서 사용되는 캐시입니다.
  • TLB를 사용하지 않으면 모든 가상메모리 참조는 두번의 메모리 참조가 필요하기 때문에 사용합니다.
    • 페이지 테이블 항목을 참조할 때 한번
    • 실제 물리메모리를 찾아갈 때 한번

CPU가 페이지 테이블보다 TLB를 우선적으로 참조하고 원하는 page가 TLB에 있는 경우 곧바로 frame number를 얻을 수 있습니다. 그렇지 않은 경우에는 메인 메모리에 있는 페이지 테이블로부터 frame number를 얻어옵니다.

페이지의 크기를 줄이면 어떻게 되나요?

페이지의 크기가 작아질 수록 내부 단편화가 감소하고 필요한 정보만 메모리에 있어서 효율적이지만 page table의 크기가 증가하고 디스크 이동의 효율성이 감소합니다. 그래서 최근에는 페이지의 크기를 키워주는 흐름입니다.

세그멘테이션이 무엇인가요?

페이징이 프로세스를 물리적인 단위로 일정한 크기로 나누어서 메모리에 할당하는 것이였다면 세그멘테이션은 프로세스를 논리적인 단위로 나눠서 메모리에 배치하는 것을 말합니다. 프로세스를 code, data, stack 영역으로 나누는 것 또한 세그멘테이션이라고 할 수 있습니다.

가상메모리

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

프로세스를 실행할 때 필요한 일부만 메모리에 로드하고 나머지는 디스크에 두는 방법입니다. 프로세스 전체가 물리메모리에 있는 것처럼 수행해서 물리메모리가 훨씬 많아보이게 하고 결과적으로는 적은 양의 주소공간만 사용합니다.

Demand Paging이 무엇인가요?

현재 필요한 페이지만 메모리에 올리는 것을 Demand paging이라고 합니다.

특정 부분이 물리 메모리에 올라가있는지 어떻게 알 수 있나요?

해당 페이지가 물리메모리에 있는지는 페이지 테이블의 valid-invalid bit로 구분할 수 있습니다. bit가 invalid일 때 해당 페이지가 물리메모리에 없다는 의미입니다. 따라서 처음에는 모든 페이지가 invalid로 초기화되어있고, 주소 변환 시 bit가 invalid로 되어있다면 page fault 오류가 발생합니다.

주소가 변환되는 과정에 대해서 설명해주세요.

image

  1. 하드웨어가 TLB를 확인한다.
  2. TLB hit인 경우 바로 주소를 반환하고, TLB miss인 경우 페이지 테이블을 확인한다.
  3. 페이지 테이블의 valid-invalid bit가 valid로 되어있다면 주소를 변환하고 TLB에 페이지를 올린다. invalid라면 page fault가 발생한다.
  4. page fault가 발생하면 MMU가 운영체제에 trap을 걸고 커널 모드로 들어가서 page fault handler가 invoke된다.
  5. 유효하지 않은 참조인 경우 프로세스를 종료시키고, 그렇지 않다면 빈 page frame을 얻는다. 빈 frame이 없다면 메모리에서 victim page를 선택하여 대체한다.
  6. 운영체제가 참조된 페이지를 디스크에서 메모리로 로드하고, disk I/O가 끝날 때까지 이 프로세스는 CPU를 빼앗깁니다.
  7. disk I/O가 끝나면 페이지 테이블이 업데이트 되고 valid-invalid bit가 valid로 바뀝니다. 그리고 ready queue에 프로세스를 넣어줍니다.
  8. 프로세스가 CPU를 잡게 되면 다시 이어서 수행합니다.
페이지 교체 알고리즘에 대해서 알려주세요.

page frame이 존재하지 않는 경우에는 어떤 frame이 페이지를 대체해야할지 결정해야합니다. 기본적으로 page fault rate를 최소화 하는 것이 목표이고, 이에 대한 여러 알고리즘이 존재합니다.

OPT 알고리즘(Optimal Algorithm)이 무엇인가요?

OPT 알고리즘은 가장 먼 미래에 참조되는 페이지를 교체하는 알고리즘입니다. 하지만 미래의 참조를 모두 알고있어야하기 때문에 실제로 사용하기는 어렵습니다.

FIFO(First In First Out)알고리즘에 대해 설명해주세요

FIFO 알고리즘은 제일 먼저 들어온 것을 먼저 내쫓는 알고리즘 입니다. 구현하기 쉽다는 장점이 있지만 어떤 페이지는 항상 필요할 수도 있는데 그런 경우에도 교체된다는 단점이 있습니다.

그리고 FIFO는 frame이 늘어나도 page fault가 감소하지 않고 오히려 늘어나는 경우가 존재하는 Belady’s anomaly현상이 발생할 수 있습니다. 일반적으로는 frame이 증가할 수록 page fault가 감소하지만 특정 구간에서는 증가하는 현상이 발생하는 경우가 있습니다.

LRU 알고리즘에 대해 설명해주세요

LRU 알고리즘은 가장 오래전에 참조된 것을 지우는 알고리즘 입니다. Optimal에 근접하고 Belady anomaly 가 발생하지 않는다는 장점이 있습니다. 하지만 구현하기가 어렵고 접근되는 빈도를 고려하지 않는다는 단점또한 가지고 있습니다.

연결리스트로 LRU를 구현하면 상수시간에 페이지를 찾고 삽입할 수 있습니다. 가장 최근에 삽입된 페이지를 연결리스트의 가장 앞으로 옮기는 방법을 사용하면 교체(replace)가 일어날 때 가장 뒤에 있는 페이지를 교체하면됩니다.

LFU(Least Frequently Used) 알고리즘에 대해 설명해주세요

LFU 알고리즘은 참조횟수가 가장 적은 페이지를 교체하는 알고리즘입니다. LRU에 비해서 장기적인 시간 규모를 보기 때문에 페이지의 인기도를 조금 더 정확히 파악할 수 있습니다.

LFU를 어떻게 구현할 수 있나요?

LRU 처럼 연결리스트를 사용하면 교체될 페이지를 찾는데 선형시간이 걸려 느립니다. 따라서 힙을 사용하면 최소 빈도를 갖는 페이지를 찾거나 삽입 삭제하는데 로그시간이 걸리도록 할 수 있습니다.

LRU, LFU 알고리즘을 실제로 페이징 시스템에서 사용할 수 있나요?

하드웨어의 제약으로 메모리 참조 순서와 횟수를 완벽히 추적하기 어렵기 때문에 정확한 LRU, LFU알고리즘을 정확히 구현하지는 않습니다.

대신 운영체제에서는 이 알고리즘들의 근사치를 사용합니다.

  • 참조 비트를 사용해서 오래된 페이지를 추적합니다.
  • 정기적으로 참조비트를 사용해서 새로 참조된 페이지의 에이징 값을 증가시킵니다.
  • 에이징 값이 낮은 페이지를 교체하는 방식으로 LRU알고리즘을 구현합니다.
Thrashing이 무엇인가요?

Thrashing은 프로세스 수행에 필요한 최소한의 페이지 프레임을 할당받지 못해서, 실행보다 Swapping하는데 더 많은 시간을 소모하는 현상입니다.

Thrashing이 발생하는 과정에 대해서 설명해주세요.
  1. 페이지가 부족해서 page fault가 증가한다.
  2. Swapping(I/O) 작업이 증가해서 CPU 효율성이 감소한다.
  3. OS는 Multiprogramming Degree를 높여야한다고 판단하여 또 다른 프로세스를 시스템에 추가한다.
  4. 프로세스당 할당된 페이지 프레임이 더욱 감소해서 page fault가 증가합니다.
  5. 프로세스는 Swapping으로 인해 매우 바빠져서 대부분의 시간에 CPU가 한가해집니다.
Thrashing을 어떻게 예방할 수 있나요?

Thrashing을 예방하기 위해서는 프로세스가 필요한 만큼 frame을 제공하면 됩니다. Working-Set Model, PFF(Page Fault Frequency) 등의 방법을 사용해서 프로세스에게 필요한 frame의 양을 알 수 있습니다.

Working-Set Model에 대해서 설명해주세요.

Working-Set Model은 최대한 Multiprogramming degree를 유지하면서 Thrashing을 막는 방법입니다. 참조 지역성의 원리라는 프로세스가 특정 시간동안 일정 장소를 집중적으로 참조하는 성질을 사용합니다. 이 지역성에 기반해서 프로세스가 일정 시간동안 원활히 수행되기 위해서 한꺼번에 메모리에 올라와있어야 하는 페이지의 집합을 Working Set이라고 합니다.

PFF(Page-Fault Frequency) Scheme에 대해서 설명해주세요.

PFF는 page fault의 상한과 하한을 두고 page fault rate가 상한 값을 넘으면 frame을 더 할당하고 하한 값보다 낮아지면 할당된 frame의 수를 줄이는 방법입니다.

This post is licensed under CC BY 4.0 by the author.