운영체제 관련 질문
운영체제란 무엇이죠?
<img src = https://github.com/wookjongkim/cs-study/assets/121083077/049d3667-ced9-43f7-bd7e-83c84690a1fe>
운영체제
란 컴퓨터 하드웨어와 소프트웨어 리소스를 관리하며 사용자(응용프로그램)와 컴퓨터(하드웨어) 사이의 인터페이스 역할을 하는 시스템 소프트웨어입니다.
이를 좁은 의미로 보면 커널 그 자체를 의미하고, 넓은 의미로 보면 커널과 시스템을 위한 유틸리티(GUI, 시스템콜, 드라이버(하드웨어 제어하기 위한 SW 등)를 포함합니다.
인터페이스란 서로 다른 두개의 시스템 사이에서 정보나 신호를 주고받는 경우의 점점이나 경계면
꼬리질문 1 - 그렇다면 커널이란 무엇인가요??
커널은 운영체제 코드 중에서도 핵심적인 부분을 나타냅니다. 커널은 하드웨어 제어 뿐만 아니라 메모리 및 프로세스 관리 등 다양한 운영체제 기능을 수행하고 부팅 이후 메모리에 항상 상주하고 있습니다.
꼬리질문 2 - 운영체제의 역할은 무엇인가요?? or 왜 필요한가?
운영체제는 사용자가 컴퓨터 시스템을 편리하게 사용할 수 있는 환경을 제공해주고(ex: GUI, 멀티태스킹으로 작업 동시에 하는것 처럼 느끼게),
컴퓨터 시스템 내의 자원(하드웨어 + 소프트웨어)을 효율적으로 관리하는 역할을 합니다.
커널이 무엇이죠?
커널이란 메모리에 상주하는 운영체제의 핵심 부분(하드웨어 제어 뿐 아니라, 프로세스 및 메모리 관리도 진행)을 말합니다.
기본적으로 소프트웨어가 컴퓨터 시스템에서 수행되기 위해서는 메모리에 그 프로그램이 올라가 있어야 합니다.
하지만 운영체제(+코드) 전체가 메모리에 올라가게 된다면 메모리 공간에 낭비가 심합니다.
따라서 운영체제 중 항상 필요한 부분만을 항상 필요한 부분만 메모리에 올리게 되는데 이것이 커널입니다.
참고 - 주소 공간이란 특정 프로세스가 접근할 수 있는 메모리의 범위를 나타냄.(코드,데이터,스택,힙 등 여러 세그먼트로 구성될 수 있다)
각각의 프로세스는 독립된 주소 공간을 가지며, 다른 프로세스의 주소 공간과 격리되어있다.(보호 및 안정성)
커널은 어떻게 구성되어있나요?
커널은 코드,데이터,스택으로 구성되어있습니다(or 스택으로 구성된 주소 공간을 가진다).
이때 코드 영역에는 하드웨어를 관리하기 위한 코드나 사용자에게 인터페이스를 제공하기 위한 코드, 시스템 콜 및 인터럽트 처리를 위한 코드 들을 담고있습니다.
커널의 데이터 영역에는 각종 자원을 관리하기 위한 자료구조가 저장되어있으며, 여기에 PCB가 저장되어있습니다.
커널의 스택 영역은 커널 모드에서 실행되는 프로세스나 함수들의 지역 변수나 리턴 주소 등을 저장하는 공간입니다.
꼬리 질문1 - 커널 스택 영역과 스택 영역의 차이점이 있나요??
사용자 스택 영역은 해당 프로그램만 접근할 수 있습니다. 이에 반해 커널 스택 영역은 커널이 실행 중인 모든 프로세스에서 접근할 수 있습니다
하드웨어 관련 질문
커널 모드와 사용자 모드는 무슨 차이가 있나요?? 그리고 시스템콜은 무엇이죠??
커널모드는 운영체제가 CPU의 제어권을 가지고 운영체제 코드를 실행하도록 하는 모드로, 모든 종류의 명령을 다 실행할 수 있습니다.
반면 사용자모드는 사용자 프로그램이 CPU를 받아 제한된 명령만 실행할 수 있습니다.
사용자 프로그램이 하드웨어 접근 등 보안이 요구되는 명령을 실행하기 위해서는 운영체제에게 이 명령을 대신 해줄것을 요청하는데, 이를 시스템콜이라고 합니다.
즉 프로그램이 자신 주소 공간 내에 있는 함수가 아닌 커널의 함수를 호출하는 것을 뜻합니다.
참고 - 보안이 요구되는 명령 : 특권명령(ex: 메모리 관리, I/O 명령, 프로세스 관리 등)이라 함 -> 커널 모드에서만 실행 가능
(운영체제의 or 컴퓨터 시스템의) 하드웨어는 어떻게 구성되어있을까요??
운영체제의 하드웨어는 크게 CPU, 메모리, 디스크, 입출력 장치로 구성되어 있습니다.
꼬리질문 1 - 각각의 역할을 무엇인가요?
CPU는 중앙 처리 장치로서, 프로그램의 연산 및 처리를 담당하는 핵심적인 역할을 합니다.
메모리는 CPU가 직접 접근할 수 있는 저장 공간으로, CPU 처리를 위해 임시적으로 프로그램의 코드나 데이터 등이 저장되는 공간입니다.
디스크는 메모리와 마찬가지로 데이터를 저장하는 공간입니다. 하지만 앞서 설명드린 메모리는 휘발성 기억장치인 것과 달리, 디스크는 비휘발성 기억장치이기에 한번 디스크에 저장되면 컴퓨터가 꺼지더라도 데이터가 보존됩니다.
입출력장치는 사용자와 컴퓨터간의 상호작용을 가능하게 하는 장치로서, 키보드나 마우스 모니터 등이 이에 해당합니다. 이들은 사용자의 입력을 받아들이거나, 컴퓨터의 처리 결과를 사용자에게 보여주는 역할을 합니다.
DMA(Direct Memory Access)란 무엇이죠?
DMA란 컴퓨터에서 입출력 장치와 메모리 사이의 데이터 전송을 CPU의 개입 없이 직접적으로 처리하는 기능을 뜻합니다.
일반적으로, 데이터를 메모리와 입출력 장치(로컬 버퍼) 사이에 이동시키는 작업은 CPU가 담당합니다. 하지만 이런 방식은 CPU의 부하를 증가시키고, 이로 인해 CPU의 다른 중요한 작업이 지연될 수 있습니다.
DMA는 이러한 문제를 해결하기 위해 설계되었습니다. DMA 컨트롤러는 CPU의 개입 없이 메모리와 입출력 장치 사이에서 데이터를 직접 이동시켜 CPU의 부하를 줄이고, CPU가 더 중요한 작업에 집중할 수 있게 해줍니다.
CPU가 입출력 장치 (예: 하드 디스크)에 데이터를 요청하면, 해당 장치는 자신의 로컬 버퍼 (또는 내부 버퍼)에 데이터를 불러옵니다. 데이터가 로컬 버퍼에 완전히 적재되면, 장치는 CPU에게 작업 완료를 알리기 위한 인터럽트를 발생시킵니다. 그러면 CPU는 이 인터럽트를 인식하고, 필요한 데이터를 로컬 버퍼에서 메인 메모리로 옮기는 작업을 수행하거나, DMA를 활용하여 이 작업을 효율적으로 처리합니다.
CPU가 무엇인지랑 구성 요소 및 연산 처리 과정을 간단히 설명해주세요.
CPU는 중앙 처리 장치로서, 프로그램의 연산 및 처리를 담당하는 핵심적인 역할을 합니다.(메모리에 있는 명령어 해석해서 실행하는 일꾼)
이러한 CPU는 제어 장치, 레지스터, 산술 논리 연산 장치로 구성되어있습니다.
제어장치는 명령어를 읽고 해석하며, 데이터 처리를 위한 순서를 결정합니다.
레지스터는 CPU 안에 있는 매우 빠른 임시기억 장치로 연산에 사용되는 데이터나 중간 결과를 보관하고 있습니다.
산술 논리 연산 장치(ALU)는 덧셈 뺄셈과 같은 두 숫자의 산술 연산과, 논리 연산을 계산하는 디지털 회로입니다.
연산 처리 과정에서 우선 제어장치가 메모리와 레지스터에 계산할 값을 로드합니다.
이후 제어장치가 레지스터에 있는 값을 계산하라고 산술논리연산 장치에 명령 한 후, 계산된 값을 다시 레지스터에서 메모리로 계산한 값을 저장합니다.
메모리 계층 구조에 대해 설명해주세요.
메모리 계층 구조는 레지스터, 캐시 메모리, 주기억 장치, 보조기억 장치로 나뉩니다.
레지스터는 CPU 내에 위치하며, (CPU가 접근할 수 있는) 가장 빠른 접근 속도를 가진 메모리입니다.
캐시 메모리는 CPU와 직접 연결되어 있는 메모리로, 자주 사용되는 데이터나 명령어를 빠르게 접근(캐시)하기 위한 메모리입니다.(L1,L2,L3 등 계층으로 구성될 수 있음)
주기억장치는 RAM을 가리키며, (CPU가 필요로 하는)시스템이 실행중인 데이터와 프로그램을 임시적으로 저장합니다.
보조 기억 장치(하드, ssd 등등)는 대용량의 데이터를 영구적으로 저장하는 사용되며, 접근 속도는 느리지만 저장 용량이 크고 비용이 저렴합니다.
타이머란 무엇인가요?
타이머는 정해진 시간이 지나면, 인터럽트를 발생시켜 운영체제가 CPU의 제어권을 획득할 수 있도록 하는 하드웨어입니다.
보통 이때 운영체제가 CPU 제어권을 얻으면, 현재 실행 중인 프로세스를 중지하고(현재 프로세스가 너무 오래 점유하거나, 자원 과도히 사용) 다음 프로세스에게 CPU를 넘겨줍니다.
MMU(Memory Management Unit)이 무엇인가요?
MMU(Memory Management Unit)는 CPU와 메모리 사이에 위치한 하드웨어 장치로서, 논리적 주소를 물리적 주소로 변환하는 주소 변환 역할을 합니다. 예를 들어, CPU가 논리적 주소 1번지에 있는 내용을 요청하면, MMU는 기준 레지스터에 저장된 값을 이 주소에 더해 물리적 주소를 계산합니다. 이렇게 변환된 주소는 물리 메모리의 실제 위치를 가리킵니다.
참고 - 이는 메모리 상 데이터가 연속적으로 존재할때만 가능
인터럽트란 무엇인가요?
인터럽트란 프로그램을 실행하고 있는 도중에 입출력 요청 또는 예외상황등이 발생했을때, 현재 실행하던 작업을 잠시 멈추고 CPU가 해당 작업을 우선적으로 처리하도록 하는 메커니즘입니다.
이때 해당 인터럽트를 처리하기 위한 특정 루틴(인터럽트 서비스 루틴)을 실행합니다.
(처리 작업 후 원래 진행중인 작업으로 돌아감)
인터럽트 요청하는 경우 : 입출력 작업이 필요한 경우, 오류나 예외 터지는 경우, 시스템콜(운영체제에 서비스를 요청할때 사용하는 인터럽트), 하드웨어 오류 등
인터럽트를 통해 입출력 연산이 이루어지는 과정에 대해 설명해주세요
현재 CPU가 메모리에 로드된 프로세스 A의 명령을 수행중이고, 프로세스 A에서 입출력 명령을 내리는 경우라고 생각해보겠습니다.
사용자 모드에서 실행되는 프로세스는 직접 입출력 장치에 명령을 내릴 수 없습니다(특권명령이라서). 그렇기 때문에 프로세스 A는 시스템 콜을 통해 운영 체제에게 작업을 요청합니다.
이때 요청은 인터럽트를 통해 CPU에 알립니다. CPU는 이 인터럽트를 인지하고 현재 수행 중인 작업을 일시 중단하며 제어권을 운영 체제에 넘깁니다
운영 체제는 해당 인터럽트를 처리하기 위한 루틴을 수행하고, 이때 필요한 입출력 작업에 대한 요청을 입출력 장치의 컨트롤러에게 전달합니다.
입출력 작업은 일반적으로 시간이 오래 걸리기 때문에, 운영 체제는 CPU의 제어권을 다른 프로세스, 예를 들면 프로세스 B에게 넘깁니다
입출력 작업이 완료되면, 해당 장치의 컨트롤러는 다시 CPU에게 인터럽트를 발생시키고, CPU는 (프로세스 B를 일시정지)인터럽트 처리 루틴에 따라 필요한 작업을 수행합니다.
이때 로컬버퍼에 있는 프로세스 A가 요청한 데이터를 A 내부의 메모리 영역으로 읽어옵니다. 그리고 CPU제어권은 다시 프로그램B에게 넘어가게 됩니다.
꼬리질문 1 - 그런데 이 과정에서 프로그램이 중단되었다가 다시 실행되는 것이 어떻게 가능할까요?
이 과정은 Context Switching(문맥 교환)에 의해 가능합니다.
문맥 교환은 CPU가 특정 프로세스의 실행 상태를 저장하고, 다른 프로세스의 상태를 불러오는 과정을 의미합니다. 여기서 프로세스의 “상태”란 PCB(Process Control Block)에 저장되는 정보를 의미하는데, PCB는 프로세스의 레지스터 상태, 프로그램 카운터, 스택 포인터, 메모리 정보 등을 포함합니다.
인터럽트가 발생했을때, 현재 실행중인 프로세스의 PCB 정보를 메모리에 저장하고, 처리해야 할 인터럽트 또는 다음에 실행될 프로세스의 PCB 정보를 불러옵니다.CPU는 이 PCB 정보를 기반으로 해당 프로세스 (+ 인터럽트 처리 루틴)를 정확히 이어서 실행할 수 있습니다.
(마치 동시에 실행되는 것처럼 보이기도 함)
PCB란 무엇인가요?
운영체제가 시스템 내의 프로세스들을 관리하기 위해 프로세스마다 유지하는 정보들을 담는 커널 내 데이터 영역에 저장됩니다.
이러한 PCB에는 프로세스의 레지스터 상태, 프로그램 카운터 값, 스택 포인터, 메모리 관리 정보 , CPU 스케줄링 정보 등을 담고있습니다.
꼬리질문 1 - 위와 같은 정보들이 왜 필요한거죠??
이러한 정보들이 필요한 이유는 운영체제가 각 프로세스를 효율적으로 관리하고, 필요한 작업을 수행하기 위함입니다
예를 들어, 프로세스의 상태 정보는 프로세스가 어떤 상태에 있는지를 알려주어, 해당 프로세스에 대한 적절한 작업을 수행하게 합니다.
메모리 관리 정보는 프로세스의 메모리 사용을 추적하고 관리하는데 사용되며, 이는 메모리 누수와 같은 문제를 방지하고, 메모리 사용의 효율성을 높이는 데 도움이 됩니다
프로그램 카운터와 레지스터들의 정보는 프로세스가 중단된 후에도 프로세스의 실행을 재개할 수 있도록 돕습니다. 이 정보를 이용하면 프로세스의 현재 상태를 저장하고, 필요한 경우에 원래의 상태로 복원할 수 있습니다.
따라서, 이러한 정보들은 프로세스의 관리와 실행을 위해 꼭 필요한 정보들입니다.
참고 - 프로그램 카운터는 다음에 실행될 명령어의 주소를 가리키는 레지스터.
스택포인터는 현재 스택의 최상단 주소를 가리키는 레지스터로, 함수 호출이나 지역 변수의 저장 등에서 사용되는 스택의 위치를 나타냅니다.(이게 있어야 스택 위치 알수 있음)
프로세스와 스레드 관련 질문
프로세스란 무엇이죠?
프로세스란 운영체제에서 실행 중인 프로그램으로 운영체제로부터 CPU,메모리 공간 등의 시스템 자원을 할당받아 작업을 수행합니다.
각 프로세스는 독립된 메모리 영역(code,data,stack,heap)을 가지며, 이 영역은 다른 프로세스로 부터 보호되어 접근 할 수 없습니다.
꼬리질문 1 - 어떻게 다른 프로세스가 해당 프로세스 영역에 접근하지 못하는 것이죠??
프로세스가 자신에게 할당되지 않은 메모리 영역에 접근하려고 하면 운영체제가 이를 잘못된 메모리 접근으로 판단하고 해당 프로세스를 종료하기 때문입니다.
프로세스의 주소 공간(프로세스 or 프로그램 구조 or 메모리 구조)에 대해 설명해주세요
프로세스 주소 공간이란 운영체제가 각 프로세스에게 할당하는 독립적인 메모리 영역으로 코드, 데이터, 스택, 힙 영역으로 나누어져 있습니다.
코드 영역에는 실행할 프로그램의 코드가 (CPU가 해석 가능한) 기계어 형태로 저장되는 영역입니다.(읽기 전용)
데이터 영역에는 (코드가 실행되면서 사용되는) 전역 변수나 정적 변수(static)가 저장되는 영역입니다.
스택 영역은 함수 호출과 관련된 정보, 예를 들어 지역 변수나 복귀 주소(함수 종료 후 제어가 돌아갈 곳)등이 저장되는 공간입니다.
이때 함수 호출이 발생하면 해당 정보는 스택에 푸쉬되고, 함수가 반환되면 스택에서 팝됩니다.
마지막으로 힙 영역은 프로세스가 동적으로 메모리를 할당받는 공간입니다. 즉 프로세스 실행 중에 필요 따라 메모리를 할당하거나 해제하는 영역입니다.
나눈 이유 - 프로그램의 각 요소들이 수행하는 역할에 따라 필요한 메모리 영역을 제공함. 메모리 효율적 관리.
영역 분리하면 메모리 접근 권한을 통해 보안을 강화 가능.
프로세스 상태 변화 과정을 설명해주세요.
프로세스는 생명 주기 동안 여러 상태 변화를 겪습니다.
new 상태는 프로세스가 생성중인 상태를 뜻합니다(메모리 획득 승인 받지 못한 상태). 그러다 프로그램이 메모리에 올라가고 CPU를 할당받기 위해 기다리는 경우 이를 ready 상태라고 합니다.
ready 상태에서 프로세스가 CPU를 획득하여 명령을 수행중인 상태는 running 상태라고합니다.
입출력 명령을 기다리는 동안 프로세스는 CPU를 빼앗기게 되고 CPU를 할당 받더라도 당장 명령을 수행할 수 없는 상태가 되는데, 이를 blocked(봉쇄)상태라고 합니다.
운영체제는 너무 많은 프로세스가 메모리에 올라와 있으면 당장 사용하지 않는 프로세스를 통째로 디스크에 쫓아냅니다. 이렇게 통째로 디스크로 swap out된 프로세스의 상태는 suspended 상태라고 합니다.
이때, ready 상태의 프로세스가 swap out 되어서 디스크에 있는 상태를 Ready Suspend (Suspended Ready) 상태라고 하고, blocked 상태의 프로세스가 swap out된 상태를 Blocked Suspend (Suspended Blocked) 상태라고 합니다.
프로세스의 모든 실행이 완료되었거나, 얘기치 않은 오류로 인해 종료된 경우는 terminated 상태라고 합니다.
-참고-
추가로, 운영체제가 메모리 공간이 충분해질 때, 디스크에서 메모리로 프로세스를 다시 옮기는 과정을 swap in이라고 합니다. 이 과정을 통해 프로세스는 다시 ready 상태로 돌아오게 됩니다.
꼬리질문 1 - 흠.. blocked 상태와 suspended 상태의 차이가 뭐죠?
Blocked 상태와 Suspended 상태의 차이는 크게 두 가지입니다.
Blocked 상태는 프로세스가 메모리에 있지만 특정 이벤트(예를 들어, 입출력 작업의 완료)를 기다리고 있어 CPU를 사용할 수 없는 상태를 나타냅니다. 이와는 달리, Suspended 상태는 시스템의 메모리 부족 혹은 운영체제의 관리 정책 등에 의해 프로세스가 메모리에서 디스크로 옮겨진 상태를 의미합니다
두 번째 차이점은 프로세스가 Ready 상태로 돌아가는 방법에 있습니다. Blocked 상태의 프로세스는 자신이 기다리고 있는 이벤트가 완료되면 바로 Ready 상태로 돌아갑니다. 반면에, Suspended 상태의 프로세스는 외부에서 명시적으로 Resume 명령을 받아야만 다시 Ready 상태로 돌아갈 수 있습니다
Resume 명령은 일반적으로 프로세스가 Suspended 상태에서 다시 Ready 상태로 돌아가기 위해 필요한 명령을 의미
유저 모드 Running -> 커널 모드 Running은 시스템콜,인터럽트, 트랩등에 의해, 이후 복귀
Running -> Blocked : 입출력 요청, Blocked -> Suspended Blocked 스왑 아웃, 스왑 인, Ready -> Suspended Ready : 스왑아웃, 스왑 인
block -> wait : 입출력 작업이 완료된 경우 Suspended Blocked -> Suspended Ready : 입출력 작업 완료된 경우
프로세스는 다양한 상태가 존재하네요. 스케줄러를 통해 이를 어떻게 관리하는지 설명해주세요.
운영체제는 프로세스들을 관리하고 스케줄링 하기 위한 큐를 두고 있습니다.(커널 데이터 영역에)
Ready Queue
는 ready 상태의 프로세스들을 줄세우고, device queue는 device 입출력 작업을 대기하고 있는(blocked) 큐입니다.
그리고 job Queue는 시스템 내의 모든 프로세스를 관리하는 큐(위 두개 다 포함하는 상위개념)입니다.
각 큐에 줄서 있는 프로세스들을 관리하기 위한 스케줄러는 총 3종류로 존재합니다.
장기 스케줄러는 프로세스를 ready queue에 진입시킬지를 결정합니다. 즉 프로세스의 메모리 할당에 관여합니다.
중기 스케줄러는 어떤 프로세스를 스왑 아웃(메모리 공간의 효율성을 위해) 시킬지 결정하고, 단기 스케줄러는 ready 상태 프로세스 중 어떤 프로세스에게 CPU를 줄지 결정합니다.
중기 스케줄러 스왑 아웃 우선순위 1순위 - block 상태 프로세스, 2순위 타이머 인터럽트에 의해 ready 상태가 된 프로세스
중기 스케줄러로 인해 프로세스 상태에는 중지라는 상태가 추가됨
중지 상태에 있는 프로세스(ex: 메모리가 부족하여 봉쇄 상태에서 중지 상태로 바뀐 경우, 준비 상태에서 중지 상태로 바뀐 경우)는 외부에서 재개시키지 않는 이상 다시 활성화될 수 없기에 메모리 자원이 당장 필요하지 않습니다. 따라서 중지 상태의 프로세스는 메모리를 통째로 빼앗기고 디스크로 스왑아웃됩니다.
Context Switching이란 무엇이고 왜 필요한것이죠??
여러 프로세스를 처리해야 하는 상황에서 현재 진행중인 Task(프로세스, 스레드)의 상태를 PCB에 저장하고 다음에 진행할 Task의 PCB정보를 읽어 레지스터에 적재하는 과정을 뜻합니다.
이를 통해 CPU가 이전에 진행했던 과정을 연속적으로 수행할 수 있습니다.
이렇게 컨텍스트 스위칭을 통해 예를들어 CPU는 I/O 작업이 실행되어 블로킹 상태에 놓인 태스크에서 다른 태스크로 전환할 수 있습니다. 이는 CPU가 I/O 작업의 대기 시간 동안 유휴 상태에 놓이는 것을 방지하고, 더 효율적으로 CPU를 활용할 수 있게 합니다
또한, 컨텍스트 스위칭 덕분에 운영체제는 여러 프로세스를 동시에 처리하는 것처럼 보이게 함으로서 시분할 시스템 또는 멀티태스킹을 실현합니다
그러나 이 과정은 오버헤드를 발생시키며, 이 시간 동안 CPU는 실제 작업을 수행할 수 없습니다. 그렇지만 일반적으로 이 오버헤드 시간은 I/O 작업 시간에 비해 훨씬 짧기 때문에, 컨텍스트 스위칭이 시스템의 전반적인 효율성을 향상시키는 데에 기여합니다
유사질문 1 - 컨텍스트 스위칭은 주로 어떤 경우 발생하나요??
컨텍스트 스위칭은 타이머 인터럽트나, 입출력 요청 등에 의해 주로 발생합니다.
실행 중인 프로세스가 할당된 시간을 모두 소비하면, 운영체제는 타이머 인터럽트를 발생시키고 CPU의 제어권을 넘겨받습니다. 운영체제는 실행 중이던 프로세스의 상태를 저장하고, 다음으로 실행할 준비 상태의 프로세스를 선택하여 그 프로세스에게 CPU의 제어권을 넘깁니다. 이를 통해 CPU는 다양한 프로세스를 공평하게 실행할 수 있게 됩니다
실행 중인 프로세스가 입출력 작업을 요청하면, 해당 프로세스는 봉쇄 상태로 전환됩니다. 이때 운영체제는 준비 상태에 있는 다른 프로세스를 선택하여 CPU의 제어권을 넘깁니다. 이는 입출력 작업이 완료될 때까지 CPU가 유휴 상태에 머무르는 것을 방지하고, CPU의 활용도를 높입니다
참고- 이때 준비 상태에 있는 프로세스중 어떤 프로세스에게 CPU를 할당할지 결정하고, 해당 CPU에게 제어권을 넘겨주는 과정을 디스패치라고 함.
CPU가 다른 프로세스로 전환하면 시스템은 프로세스의 상태를 PCB에 저장한다.
대기열에서 다음 프로세스를 선택하고 PCB를 복원 한다.
PCB의 프로그램 카운터(레지스터) 가 로드되어 선택한 프로세스에서 실행을 계속한다.
프로세스 생성 과정에 대해 설명해주세요.
우선 PCB가 생성되고 OS가 실행한 프로그램의 코드를 읽어서 프로세스에 할당된 메모리의 코드 영역에 저장합니다.
그리고 초기화된 전역 변수와 static 변수는 데이터 영역에 할당되고, 힙과 스택 영역의 메모리 주소도 초기화 됩니다.
이렇게 모든 정보와 데이터가 할당 및 초기화 된 후, 프로세스는 Ready Queue에서 cPU의 할당을 기다리게 됩니다.
IPC(Inter Process communication)란 무엇인가요?
IPC란 다른 프로세스간에 데이터를 주고 받을 수 있게 해주는 메커니즘입니다. 즉 독립적으로 실행되는 프로세스들 사이에 정보를 교환하게 해줍니다.
IPC는 두 개 이상의 프로세스가 같은 메모리 영역을 공유하면서 데이터를 읽거나 쓰는 방식인 메모리 공유 방식이나 프로세스 간에 메세지를 주고 받는 방식(파이프, 소켓)을 통해 이루어 집니다.
—참고—
이러한 IPC 메커니즘은 다양한 방식으로 구현될 수 있습니다.
첫번째는 익명 파이프(PIPE)입니다. 여기서 파이프란 두 프로세스간 파이프를 연결해서 통신하는 방식으로, 이때 한 프로세스는 쓰기만 가능하고 한 프로세스는 읽기만 가능합니다.
그리고 이는 한쪽 방향으로만 통신이 가능하기에 반 이중 통신이라 부르기도 합니다.(이 또한 전이중 통신위해서는 파이프 2개를 만들어야 함)
두번째로 Named Pipe(FIFO) 방식이 있습니다. 앞서 설명드린 PIPE는 통신하는 프로세스가 명확할 경우(ex: 부모-자식 프로세스간) 사용하는 반면, NamedPIPE는 전혀 모르는 사이의 프로세스들의 통신에 사용합니다.
하지만, 익명 PIPE와 동일하게 동시에 읽기/쓰기가 불가능 하고, 전 이중 통신을 위해서는 익명 파이프처럼 2개를 만들어야 가능합니다.
메세지 큐는 프로세스 간 메세지를 주고 받는 방식으로, 일반적으로 큐 자료구조를 이용하여 구현됩니다.이때 메세지를 보내는 프로세스는 메세지 큐에 메세지를 넣고, 메세지를 받는 프로세스는 메세지 큐에서 메세지를 가져옵니다.
공유 메모리 방식은 두개 이상의 프로세스가 동일한 물리적 메모리 공간을 공유하여 데이터를 주고 받는 방식입니다.
프로세스가 공유 메모리 할당을 커널에 요청하면 커널은 해당 프로세스에 메모리 공간을 할당해줍니다. 이후 어떤 프로세스건 해당 메모리영역에 접근할 수 있습니다. 공유 메모리는 곧바로 메모리에 접근할 수 있기 때문에 IPC 방식 중 속도가 제일 빠릅니다(근데 동기화 고려해야).
소켓(Socket)은 네트워크에서 동작하는 프로세스 간에 데이터를 교환하는 방식으로 서로 다른 시스템에 있는 프로세스들 사이에서 데이터를 주고 받을 때 적합합니다.
이때 서버 프로세스는 특정 포트에서 들어오는 클라이언트 연결을 수신하기 위해 소켓을 열고 대기하고, 클라이언트 프로세스는 서버의 IP와 포트를 알고 있어야 연결을 수립할 수 있습니다.
참고 - 메세지큐는 FIFO, 여러 프로세스가 동시에 큐에 접근하여 메세지를 읽고 쓸 수 있다는 것입니다. 각 프로세스는 메세지를 큐에 추가하거나 큐에서 메세지를 꺼내어 처리하며, 이 방식을 통해 여러 프로세스 간에 데이터를 공유할 수 있습니다.
메세지 큐는 메모리 내에 위치하여 빠른 속도로 데이터를 전달하고, 프로세스가 종료되어도 큐에 있는 메세지는 사라지지 않습니다. 이러한 특성 때문에 메세지 큐는 서로 다른 라이프 사이클을 가진 프로세스간의 통신에 적합합니다.
프로세스와 스레드의 차이를 설명해주세요.
프로세스란 운영체제에서 실행 중인 프로그램으로 운영체제로부터 CPU,메모리 공간 등의 시스템 자원을 할당받아 작업을 수행합니다.
스레드는 한 프로세스 내의 실행 단위를 뜻합니다. 스레드 ID, PC, 레지스터 집합, 스택(이 4가지로 구성되었다고 봐도됨)은 독립적으로 할당되고 나머지 (프로세스)자원들은 공유하며 사용하는 것이 특징입니다.
참고
같은 프로세스의 다른 스레드와는 코드 영역, 데이터 영역, 운영체제 자원등을 공유함.
프로세스의 경우 각각 code,data,stack,heap을 보유하기에 동기화 작업이 필요하지 않지만, 각각의 영역을 가져서 컨텍스트 스위칭 비용이 크다.
스레드는 stack만 고유 영역을 가지고, 나머지는 프로세스 자원을 공유
stack 이외의 영역을 공유하므로, 동기화 작업이 필요하지만, 컨텍스트 스위칭 비용이 적음
각각의 실행 위치를 알려주기 위해 PC를, 수행중인 값을 임시적으로 저장하기 위한 레지스터 집합 공간을 별도로 가져야 합니다
스레드마다 스택을 독립적으로 할당하는 이유가 뭐죠?
스택을 사용하여 함수 호출 시의 인자, 반환 주소, 지역 변수 등을 저장합니다.
스택 메모리 공간이 독립적이라는 것은 독립적인 함수 호출이 가능함을 의미하고 이는 독립적인 실행 흐름이 추가된다는 것을 의미합니다.
즉, 독립적인 실행 흐름을 만들기 위해서 스레드마다 스택을 할당합니다.
스레드마다 PC 레지스터를 독립적으로 할당하는 이유가 뭐죠?
PC (Program Counter) 레지스터는 현재 스레드가 수행 중인 명령어의 주소를 저장합니다. 각 스레드는 독립적인 실행 흐름을 가지므로, 어느 명령어를 실행하고 있는지를 추적하기 위해 독립적인 PC 레지스터가 필요합니다. 이렇게 함으로써, 스레드가 중단된 후 다시 시작될 때, 이전에 중단된 위치에서 실행을 재개할 수 있습니다.
메모리의 힙 영역과 스택 영역의 차이에 대해 설명해주세요.
스택 영역은 지역변수, 매개변수 등 저장하고 힙 영역은 동적으로 생성된 변수가 저장됨
스택은 컴파일시 크기가, 힙 영역은 런타임시 결정됨
스택은 크기 제한 있다, 힙 영역은 크기 제한 X
스택은 함수 종료와 함께 소멸되므로 별다른 관리 필요 없지만, 힙 영역은 관리 필요
두 영역은 같은 물리 메모리 공간을 공유하는데, 스택은 높은 주소에서 낮은 주소로, 힙은 낮은 주소에서 높은 주소로 채워지기 때문에 서로의 영역을 누가 침범하느냐에 따라 heap overflow, stack overflow가 발생할 수 있습니다.
참고로, 메모리의 위쪽에 위치할 수록 낮은 주소이며, 아래쪽에 위치할 수록 높은 주소입니다.
멀티 스레드와 멀티 프로세스의 차이가 뭐죠?
하나의 프로그램을 여러 프로세스로 동작시키는 것을 멀티 프로세스라고 하구요, 여러 스레드로 동작시키는 것을 멀티 스레드라고 합니다.
꼬리질문 1 - 각각 언제 사용하는 것이 좋을까요?
CPU가 처리해야하는 task의 특성이 크기가 크지 않으면서 개수가 많을 경우나 실시간성이 중요한 웹과 같은 경우 멀티 스레드를 사용하는 것이 좋구요, CPU가 처리해야하는 task의 특성이 크기가 크면서 개수가 적은 경우나 실시간성이 중요하지 않은 일괄 처리 같은 경우 멀티 프로세스를 사용하면 좋습니다.
꼬리질문 2- 각각의 장단점에 대해 알려주세요.
멀티 프로세스는 여러 프로세스 중 하나의 프로세스에 문제가 발생한다면 해당 프로세스에서만 문제를 해결하면 되기 때문에 멀티 스레드에서 비해서 상대적으로 안정적이라는 장점이 있지만
프로세스간에 공유 되어지는 메모리가 없기 때문에 프로세스 간의 통신을 위해서 통신 기법이 필요합니다. 이 뿐만 아니라 멀티 스레드보다 많은 메모리 공간을 차지하는 단점이 있습니다(context Switching도 오래 걸려)
멀티 쓰레드는 하나의 프로세스 내에서 스레드들이 메모리와 자원을 공유하기에 메모리 사용이 효율적이고, Context Switching이 빠른 장점이 있지만 오류로 인해 하나의 스레드가 종료되면 전체 스레드가 종료될 수 있다는 점과 (Code, Heap, Data 메모리 영역을 공유하기 때문에)동기화 문제를 가지고 있습니다.
멀티 쓰레드는 한 쓰레드가 블로킹에 있을때, 다른 스레드가 실행될 수 있어 빠른 응답 또한 제공 가능
멀티 프로세스가 멀티 쓰레드에 비해 Context Switching 오래 걸리는 이유
프로세스는 스레드에 비해 더 많은 시스템 자원을 독립적으로 관리합니다. 이로 인해 프로세스의 상태 정보(Context)는 스레드의 상태 정보보다 크기가 크며, 이 정보를 저장하고 불러오는 작업에 더 많은 시간이 소요됩니다.
멀티 쓰레드가 문맥 교환 빠른 이유 - 스레드 간에 많은 자원(메모리, 코드, 데이터 영역)을 공유하기 때문에 저장 및 복원해야 하는 정보량이 줄어들기 때문입니다.
꼬리질문 3 - 멀티 프로세스 대신 멀티 스레드를 사용하는 이유
- 프로그램을 여러 개 키는 것보다 하나의 프로그램 안에서 여러 작업을 해결하는 것이 더욱 효율적이기 때문
- 컨텍스트 스위칭 시 stack 영역만 초기화하면 되기 때문에 더 빠르다.
- 프로세스를 생성하여 자원을 할당하는 콜이 줄어들어 자원을 효율적으로 관리할 수 있다.
멀티 프로세스도 동기화 문제 발생 가능(ex: 자원 공유시)
꼬리질문 4 - 멀티 쓰레드 상황에서 동시성문제 어떻게 해결하냐
자바에서 제공하는 synchronized 키워드를 사용해서 특정 코드 블록이나 메서드에 대해 한번에 하나의 스레드만 해당 코드를 실행하도록 할 수 있음.
자바 동시성 라이브러리 활용통해서도 가능(ex: ReentrantLock, Semaphore, CountDownLatch)
기존의 ArrayList나 HashMap 대신 CopyOnWriteArrayList, ConcurrentHashMap 같은 thread-safe 컬렉션을 사용하여 동시성 문제를 해결할 수 있습니다
데이터베이스의 Isolation Level 조정: 스프링의 트랜잭션 관리를 이용하여 데이터베이스의 isolation level을 조정함으로써 동시성 문제를 완화(또는 해결)할 수 있습니다
Optimistic & Pessimistic Locking: 데이터의 동시 수정을 방지하기 위해 낙관적 락킹과 비관적 락킹 방법을 사용할 수 있습니다. JPA에서는 @Version 어노테이션을 이용하여 낙관적 락킹을 구현할 수 있습니다.
Atomic 클래스 활용: Java의 AtomicInteger, AtomicReference 등의 atomic 클래스를 사용하여 원자적 연산을 보장받을 수 있습니다.
CPU 스케줄링 관련 질문
CPU 버스트와 I/O 버스트에 대해 아시나요?
사용자 프로그램이 CPU 제어권을 가지고 빠른 명령을 수행하는 일련의 단계를 CPU 버스트라고 부르고, I/O 요청이 발생해 커널에 의해 입출력 작업을 진행하는 비교적 느린 단계를 I/O 버스트라고 부릅니다.
참고 - CPU 프로세싱은 이와 같이 패턴이 상이한 여러 프로그램이 동일한 시스템 내부에서 함께 실행되기에 필요
대부분은 CPU를 오래 사용하기보단, 잠깐 사용하고 I/O 작업을 수행하며, 짧은 CPU 버스트를 가진 프로세스에게 우선적으로 CPU 할당하는 것이 이득일 수 있다.
디스패치에 대해 아시나요?
디스패치는 현재 실행 중인 프로세스의 문맥(context)을 해당 프로세스의 PCB(Process Control Block)에 저장한 다음, 다음으로 선택된 프로세스의 문맥을 해당 프로세스의 PCB에서 복원하여 CPU의 제어를 그 프로세스에게 넘기는 과정을 의미합니다.
CPU 스케줄링이란 무엇이고, 어떠한 경우 필요할까요??
CPU 스케줄링이란 준비 상태에 있는 프로세스들 중 어떠한 프로세스에게 CPU를 할당할지 결정하는 것으로, 비 선점형 방식과, 선점형 방식이 있습니다.
비 선점형은 CPU를 획득한 프로세스가 스스로 CPU를 반납하기 전까지 CPU를 빼앗기지 않는 방법이고, 선점형 방식은 프로세스가 CPU를 계속 사용하기를 원하더라도 강제로 빼앗을수 있는 방식입니다.
만약 실행 상태에 있던 프로세스가 I/O 요청에 의해 봉쇄 상태가 되거나(비선점형), 실행 상태에 있던 프로세스가 타이머 인터럽트(선점형)에 의해 준비상태로 바뀌는 경우, CPU 이용률을 높이기 위해 다른 프로세스에게 CPU 제어권을 넘기는 과정에서 CPU 스케줄링이 필요합니다.
또한 CPU에서 실행상태에 있던 프로세스가 종료되는 경우도 예시로 들수 있습니다.
여러가지 CPU 스케줄링 기법은 어떻게 평가되나요?
A) 시스템 관점에서는 CPU 이용률과 처리량(throughput)을 높이는 데 목적이 있고 개별 프로세스 관점에서는 응답시간, 대기시간, 소요시간을 짧게 하는 것이 목적입니다.
이때 응답시간(response time)은 준비상태의 프로세스에게 최초로 CPU가 할당되기까지 걸린 시간,
대기 시간은 ready 상태에서 CPU를 기다린 총 시간(시분할 시스템의 경우 타이머 인터럽트로 인해 기다리는 시간 여러번 있겠지?),
소요시간은 준비큐에서 기다린 시간과 실제로 CPU를 사용하는 시간의 합을 뜻합니다.(원하는 만큼 CPU 다쓰고 CPU 버스트가 끝나기 까지 걸린 시간).
참고 - CPU 이용률은 전체 시간 중 CPU가 일을 한 시간의 비율을 나타냅니다
처리량(Throughput)은 주어진 시간 동안 준비 큐에서 기다리고 있는 프로세스 중 몇 개를 끝마쳤는지를 의미합니다.
여러가지 CPU 스케줄링 기법에 대해 간략히 설명해주세요.
CPU스케줄링은 두 가지로 나눌 수 있습니다. 비 선점형은 CPU를 획득한 프로세스가 스스로 CPU를 반납하기 전까지 CPU를 빼앗기지 않는 방법이고, 선점형 방식은 프로세스가 CPU를 계속 사용하기를 원하더라도 강제로 빼앗을수 있는 방식입니다
FCFS(선입 선출: First Come First Served) 스케줄링은 먼저 온 프로세스부터 CPU를 할당하며, 비 선점형 스케줄링입니다. 이때 소요시간이 긴(CPU 버스트가 긴) 프로세스가 먼저 도착해 버리면 전체적으로 프로세스들의 효율성을 낮춘다는 단점을 갖고 있습니다.(콘 보이)
SJF 스케쥴링은 CPU 버스트가 가장 짧은 프로세스에게 제일 먼저 CPU를 할당하는 방식으로, 비 선점형 방식으로 동작합니다.
이때 CPU 버스트가 긴 프로세스는 오랜시간 CPU를 할당받지 못해 starvation 문제가 발생할 수 있습니다.
SRTF는 SJF와 유사하나 중간에 새로운 프로세스가 도착하면 새로 스케줄링을 합니다. 따라서 선점형 스케줄링이며 현재 실행중인 프로세스의 남은 CPU버스트 시간보다 더 짧은 CPU버스트시간을 가지는 프로세스가 도착하면 CPU를 빼앗깁니다. 즉 잔여시간을 우선으로 하는 스케줄링 방식입니다.
Priority Scheduling은 우선순위대로 CPU를 할당해주는 스케줄링으로 비선점형,선점형 방식으로 각각 구현할 수 있습니다. 선점형 스케줄링 방식에서는 더 높은 우선 순위의 프로세스가 도착하면 그 프로세스에게 CPU를 빼앗기고 비선점형 스케줄링 방식에서는 더 높은 우선순위의 프로세스가 도착하더라도 그 프로세스는 우선 ready queue에 위치하게 됩니다.
우선순위가 높은 프로세스가 계속 도착하는 상황에서는 우선순위가 낮은 프로세스는 CPU를 얻지 못한 채 계속 기다려야하는 starvation 문제가 발생할 수 있습니다.
이는 보통 aging 기법으로 해결할 수 있는데, aging 기법이란 오래 기다린 프로세스에게 우선순위를 높여주는 방법입니다.
마지막으로 Round-Robin 방식은 (시분할 시스템의 성질을 가장 활용한 스케줄링 방식으로), 각 프로세스가 CPU를 연속적으로 사용할 수 있는 시간을 특정 시간으로 제한하고, 시간 경과 시 해당 프로세스로부터 CPU를 회수해 준비 큐에 줄 서 있는 다음 프로세스(준비 큐 맨앞)에게 CPU를 할당하는 방식입니다.
특정 프로세스의 독점을 방지할 수 있고, CPU 실행시간이 랜덤한 프로세스들이 섞여있을 경우 효율적입니다.
참고
CPU 버스트가 짧은 프로세스가 CPU 버스트가 긴 프로세스 보다 나중에 도착해 오랜 시간을 기다려야 하는 현상을 콘보이 현상(Convoy Effect)
라운드 로빈에서 만약 할당 시간(time quantum, slice)을 너무 크게 한다면 FCFS처럼 동작하게 되고, 너무 짧다면 Context Switching(문맥 교환) 오버헤드가 커지기 때문에 적절한 시간을 할당하는 것이 중요합니다!
꼬리질문 1 - 어떠한 경우 선점형, 어떠한 경우 비선점형을 쓰는것이 좋은가요?
빠른 응답시간이 필요하거나 새로운 고 우선순위 작업을 즉시 처리해야 하는 경우 선점형 스케줄링을 사용하고, 예측 가능한 스케줄링이 필요하거나 오버헤드(스위칭)를 최소화해야 하는 경우 비선점형 스케줄링을 사용하는 것이 좋습니다.
MLQ 스케줄링 알고리즘과 MLFQ 스케줄링 알고리즘의 차이점은 무엇인가요?
MLQ(Multi Level Queue)와 MLFQ(Multi Level Feed Back)는 여러 개의 큐를 이용하고, 각 큐(대기열)에 별도의 스케줄링 알고리즘을 사용할 수 있는 방식입니다.(ex: 하나의 대기열엔 RR, 하나는 FCFS)
MLQ에서는 프로세스의 우선순위가 사전에 정적으로 결정되며, 한번 큐에 할당된 프로세스는 그 큐에서 실행이 완료될 때까지 다른 큐로 이동하지 않습니다.
반면에 MLFQ에서는 프로세스의 우선순위가 동적으로 결정됩니다. 이는 프로세스의 실행 상황(CPU 버스트 시간의 길이, I/O 요청의 빈도 등)에 따라 우선순위를 조정하며, 프로세스가 실행 중에 우선순위가 높아질 경우 더 높은 우선순위의 큐로 이동할 수 있게 됩니다(할당받을 가능성이 더 높아짐).
꼬리질문 - 왜 이렇게 여러개의 큐를 두는 것이죠??
여러 개의 큐를 사용하는 이유는 프로세스의 우선순위와 요구 사항에 따라 유연하게 스케줄링을 수행하기 위해서입니다.
예를 들어, CPU 집중적인 프로세스와 I/O 집중적인 프로세스가 같은 큐에 있다면, CPU 집중적인 프로세스가 계속해서 CPU를 점유할수 있고 이에 따라 I/O 작업이 필요한 프로세스는 기아 상태에 빠질 수 있습니다. 그래서 이런 상황을 피하기 위해 여러 개의 큐를 두고 각 큐에 대한 스케줄링 알고리즘을 다르게 설정하는 것입니다
비선점과 선점 SJF 스케줄링 알고리즘에 대해 설명해주세요.
둘다 CPU 점유시간이 짧은 순서대로 프로세스를 처리하는 방식입니다. 하지만 선점형의 경우엔 작업을 하고 있는 동안에 실행 시간이 짧은 프로세스가 도착하면, 작업을 멈추고 도착한 프로세스에게 CPU를 넘겨줍니다.
비선점형 SJF 방식은 실행시간이 짧은 프로세스가 계속 도착하는 경우 기아현상이 발생할 수 있고, 선점형 SJF는 잦은 context switching으로 인한 성능저하의(오버헤드 크다) 문제점이있습니다.(선점형도 역시 기아현상 가능)
입출력 관련 질문
입출력이란 무엇인가요?
외부 장치로부터 필요한 외부 장치로 부터 필요한 데이터를 받아 프로그램에서 사용하는 메모리에 저장하거나, 메모리에 있는 데이터를 외부 장치로 보내는 것을 뜻합니다.
동기식 입출력과 비동기식 입출력의 차이에 대해 아시나요?
동기식 입출력에서는 I/O 작업이 완료될 때 까지 프로세스가 대기 상태를 유지하는 반면, 비동기식 입출력에서는 I/O 작업을 요청한 후, 그 작업의 완료를 기다리지 않고 바로 다음 작업으로 넘어갑니다.
동기식 입출력은 CPU가 낭비된다는 단점이 있으므로, 보통 기다리는 시간 동안 CPU 제어권은 다른 프로세스에게 넘어가게 됩니다. 반면 비동기식 입출력은 시스템 콜로 운영체제에게 입출력 명령을 부탁한 뒤 다시 바로 CPU 제어권을 얻습니다.
인터럽트 관련 질문
인터럽트란 무엇이고 왜 필요한가요?
인터럽트는 주변 장치나 입출력 장치가(정확하게는 입출력 장치의 컨트롤러) CPU 서비스를 필요로 할때 신호를 발생시켜 서비스를 요청하는 메커니즘입니다.
예를 들어, 하드디스크에서 데이터를 읽는 작업을 CPU가 요청을 했다면, CPU는 작업이 완료될 때 까지 기다리는 대신, 다른 작업을 계속해서 수행할 수 있습니다.
이후 하드디스크가 데이터를 읽기 작업을 완료하면 (컨트롤러에서) 인터럽트를 발생시켜 CPU에 알립니다. 이러한 방식으로 CPU의 효율성을 높일 수 있습니다.
참고 - 컨트롤러란 장치내 작은 CPU로 인터럽트를 발생시켜 CPU에 보고를 하는 역할
로컬 버퍼 - 컨트롤러 내에 위치하며, 장치로 부터 들어오고 나가는 데이터의 임시 저장을 위한 작은 메모리
꼬리질문 1 - 인터럽트가 발생한 후 어떻게 프로세스는 다시 이어서 실행하나요?
인터럽트가 발생하면, CPU는 먼저 현재 수행 중이던 작업의 상태를 저장합니다. 그리고 인터럽트 요청을 처리한 후, 인터럽트가 발생하기 직전의 상태를 복구시키면서 중단되었던 작업을 재개하게 됩니다. 이렇게 함으로써, CPU는 인터럽트에 반응하면서도 본래의 작업을 계속 수행할 수 있습니다
꼬리질문 2 - 인터럽트 처리루틴이란 무엇인가요?
인터럽트 처리루틴은 운영체제가 각 인터럽트의 종류마다 가지고 있는 처리 절차입니다. 예를 들어, 키보드에서 입력이 들어오면, 운영체제는 키보드 인터럽트 처리루틴을 실행시켜 키보드로부터 입력받은 내용을 메모리의 특정 부분에 저장하고 해당 프로그램에 키보드 입력이 들어왔음을 알립니다. 이런 방식으로 운영체제는 다양한 인터럽트에 대응할 수 있습니다.
꼬리질문 3 - CPU는 인터럽트가 발생했을 때 이를 어떻게 인지하나요?
CPU는 명령하나를 수행할때마다 인터럽트가 발생했는지 인터럽트 라인을 확인하게 됩니다.
이때 인터럽트 신호가 있다면, CPU는 다음 명령을 수행하기 전 인터럽트 처리를 하게 되고, 그렇지 않으면 다음 명령을 계속 수행하게 됩니다.
인터럽트 종류에는 어떤 것들이 있을까요?
인터럽트의 종류에는 하드웨어 인터럽트와 소프트웨어 인터럽트가 있습니다.
이 둘은 CPU의 서비스가 필요한 경우, CPU 옆에 있는 인터럽트 라인에 신호를 보내어 인터럽트가 발생했다는 것을 알려주는것은 동일하나, 하드웨어 인터럽트는 컨트롤러등 하드웨어 장치가 인터럽트 라인을 세팅하는 반면, 소프트웨어 인터럽트는 소프트웨어가 인터럽트를 세팅한다는 차이점이 있습니다.
소프트웨어 인터럽트는 trap이라는 용어로 주로 불리며 예외상황, 시스템 콜 등이 있습니다.
하드웨어 인터럽트는 보통 IO 디바이스에서 발생하는 인터럽트 뜻합니다.(ex: 키보드 연결, 마우스 연결)
소프트웨어 인터럽트 중 예외상황이란 사용자 프로그램이 0으로 나누는 연산 등 비정상적 작업을 시도하거나, 자신의 메모리 영역 밖을 접근하려는 등 권한 없는 작업을 시도할때, 이에 대한 처리를 위해 발생시키는 인터럽트 입니다.
시스템콜은 사용자 프로그램이 운영체제 내부에 정의된 코드를 실행하고 싶을 때 운영체제에 서비스를 요청하는 방법입니다.
참고- 예외상황 시스템콜 모두다 인터럽트를 발생시킨 후 CPU의 제어권이 운영체제로 넘어감
인터럽트가 발생한 후 동작 방식에 대해 설명해주세요.
예를들어 B라는 프로그램이 실행 중에 I/O 작업이 필요해 시스템 콜을 통해 작업을 요청한 후 대기 상태(봉쇄 상태)에 있고, 현재 CPU는 A라는 프로그램을 실행 중이라고 가정해 보겠습니다.
장치(ex: 디스크)의 컨트롤러가 B 프로그램에 작업을 완료 시키면, CPU에게 인터럽트를 발생시킵니다.
CPU는 인터럽트를 받으면, 우선 현재 실행 중인 프로그램 A의 상태를 저장해야 합니다.
이를 위해 CPU는 프로그램 A의 정보들, 예를 들어 PC(CPU가 수행해야할 메모리 주소를 담고 있는 레지스터)나 레지스터 정보등을 PCB에 저장합니다. 이는 나중에 프로그램 A의 작업을 재개하기 위함입니다.
그런 다음에, CPU의 제어는 현재 실행 중인 프로그램에서 인터럽트를 처리하기 위한 처리루틴으로 전환됩니다.이때 CPU의 제어가 현재 프로그램에서 다른 프로그램(여기서는 처리루틴)으로 넘어가는 것을 컨텍스트 스위칭이라고합니다.
이제 CPU는 해당 인터럽트를 처리하는 루틴을 수행하게 됩니다. 이 루틴은 일반적으로 운영체제 커널의 일부로, I/O 작업의 결과를 메모리에 적재하는 등의 작업을 수행합니다.(이때 blokced를 ready 상태로 바꾸는 것도 함)
인터럽트 처리 완료후엔 앞서 저장했던 PCB에서 프로그램 A의 정보를 불러와 CPU에 복원합니다.
복원 후에 CPU는 프로그램 A의 작업을 이어서 수행할 수 있게 됩니다.
참고
레지스터란 무엇인가 - CPU내부에 있는 빠른 저장 공간으로 계산에 사용되는 데이터나 중간 결과를 보관하고 있다. 이의 예로는 PC, 명령어 레지스터, 누산기, 일반 레지스터 등이 있다.
PC란 현재 CPU가 실행중인 명령어의 주소를 가리키는 레지스터입니다.
PCB는 운영체제가 각 프로세스를 관리하기 위해 사용하는 자료구조로, 실행 중인 코드의 메모리 주소와 레지스터 및 PC의 값들이 저장됩니다.
프로세스 동기화와 데드락
프로세스 동기화는 왜 필요하나요?
공유 자원을 참조하는 프로세스 간에 질서 있는 실행을 보장하여 데이터의 일관성을 유지하고자 프로세스 동기화가 필요합니다.
Race Condition(경쟁 상태)이 무엇이죠?
Race Condition은 두개 이상의 스레드나 프로세스가 공유된 데이터나 자원에 동시에 접근하려 할때, 데이터의 최종 상태가 그 접근 순서에 따라 달라질 수 있는 상황을 말합니다.
임계 영역에 대한 경쟁 상태를 제거하기 위해서는 한 공유자원에 대해 한 쓰레드만 접근 가능하도록 하는 상호 배제를 사용
예시
이커머스 플랫폼에서 한정판 스니커즈가 1개만 남아 있다고 가정해봅시다. 두 명의 구매자 A와 B가 동시에 이 스니커즈를 구매하려고 클릭했다고 생각해보죠. 시스템은 두 명의 구매자로부터 구매 요청을 거의 동시에 받았고, 각각의 요청을 처리하기 전에 재고를 확인했을 때 스니커즈가 1개 남아 있다고 판단합니다. 그 결과, 두 명의 구매자 모두에게 구매가 완료되었다는 메시지를 보내버릴 수 있습니다. 하지만 실제로는 재고가 1개뿐이기 때문에 이러한 상황은 Race Condition으로 인한 문제가 발생한 것입니다.
Critical section이 무엇인가요?
Critical Section(임계 영역)은 여러 스레드 또는 프로세스가 동시에 접근할 수 있는 공유 데이터나 자원을 사용하는 코드 영역을 말합니다
(이 영역에서 동시에 여러 스레드가 실행될 경우 데이터의 일관성이 깨질 수 있기 때문에 한 번에 하나의 스레드만 접근할 수 있도록 동기화가 필요합니다.)
꼬리질문 1 - 임계 영역 해결하기 위한 조건에 대해 설명해주세요.
임대 영역 문제를 해결하기 위해서는 3가지의 조건을 만족시켜야합니다.
상호 배제(Mutual Exclusion) 조건은 하나의 프로세스 혹은 스레드가 임계 영역에 들어가있다면 다른 프로세스 혹은 스레드는 들어갈 수 없어야 한다는 조건입니다.
진행(Progress) 조건은 임계 영역에 들어간 프로세스 혹은 스레드가 없는 상태에서 들어가려 하는 프로세스 혹은 스레드가 여러 개라면 어느 것이 들어갈지 결정 해주어야 한다는 조건입니다.
한정 대기 조건(Bounding Waiting)은 특정 프로세스가 무한대로 기다리지 않도록 critical section에 진입하는 횟수에 제한을 두어야 한다는 것입니다.
Race Condition(or Critical Section) 해결책에 대해 말씀해주세요.
Race Condition 해결할 수 있는 방법에는 주로 세마포어와 뮤텍스를 사용합니다.
둘다 공유 자원에 대한 동시 접근을 제어하여 상호 배제를 달성하는 기법입니다.
뮤텍스는 오직 하나의 스레드나 프로세스만이 공유 자원에 접근할 수 있도록 하는 기법입니다.
따라서 반드시 락을 획득한 프로세스가 락을 해제해야 하고, 다른 스레드나 프로세스는 락이 해제될때 까지 대기하게됩니다.
(세마포어 변수 S가 1인 경우입니다. P연산(감소)을 해주면 S는 0이 되고(lock), V연산(증가)을 해주면 S는 1이 됩니다(unlock). 뮤텍스를 이진 세마포어라고 부르기도 합니다.)
세마포어는 지정된 수만큼의 스레드나 프로세스가 동시에 공유 자원에 접근할 수 있게 하는 기법입니다.
예를 들면, 세마포어의 값이 3이라면 최대 3개의 스레드나 프로세스가 동시에 해당 자원을 사용할 수 있습니다.
스레드나 프로세스가 세마포어를 사용하려고 하면, 세마포어의 값은 감소하게 됩니다. 만약 세마포어 값이 0이라면, 추가적인 스레드나 프로세스는 세마포어가 다시 증가할 때까지 대기하게 됩니다.
참고
이진 세마포어는 뮤텍스와 동일하다고 볼 수 있다. 이진 세마포어가 아닌 나머지 세마포어를 카운팅 세마포어라고 부른다.
현재 수행중인 프로세스가 아닌 다른 프로세스가 세마포어를 해제할 수 있다.
뮤텍스와 세마포어를 사용해 임계영역에서의 경쟁상태를 제거할 수 있습니다.
뮤텍스나 세마포어는 완벽한 기법 X
뮤텍스 세마포어 둘다 락 개념(정확히 세마포어는 카운트를 기반, 카운트 0이 되기 전까진 여러 스레드가 접근 가능)을 사용하여 동시 접근 제한
-> 데드락 발생 가능(스레드 A가 뮤텍스 M1을 획득하고 M2를 기다리는 동안, 스레드 B가 M2를 획득하고 M1을 기다리는 상황이 될 수 있습니다)
-> 기아 상태 발생 가능
DeadLock(교착 상태)이 무엇이죠?
두개 이상의 프로세스나 스레드가 서로 자원을 기다리면서 무한히 대기하는 상태를 뜻합니다.(아무도 완료되지 못하는 상태)
데드락(교착상태) 발생하는 조건은 무엇인가요??
교착 상태는 주로 4가지의 조건이 동시에 만족할때 발생하게 됩니다.
상호 배제는 한 자원에 여러 프로세스가 동시에 접근할 수 없는 경우입니다.
점유 대기 조건은 하나의 자원을 소유한 상태에서 다른 자원을 기다리는 경우입니다.
비 선점 조건은 프로세스가 어떤 자원의 사용을 끝날때까지 프로세스의 자원을 뻇을 수 없는 경우입니다.
순환 대기는 각 프로세스가 순환적으로 다음 프로세스가 요구하는 자원을 가지고 있는 경우입니다.
이러한 조건들이 모두 만족되면 교착 상태가 발생하게 됩니다.
데드락(교착상태) 해결 방법에 대해 설명해주세요.
예방, 회피, 탐지 및 회복, 무시 총 4가지 대처법이 있습니다.
예방
은 교착 상태 발생 조건 중 하나를 제거하면서 해결합니다.(자원 낭비 심함, 실효성 적음)
상호 배제 부정 : 여러 프로세스가 공유 자원을 사용하도록 합니다.
점유 대기 부정 : 프로세스 실행전 모든 자원을 할당하거나 자원이 필요한 경우 모든 자원을 내려놓고 다시 요청합니다.
비선점 부정 : 자원 점유 중인 프로세스가 다른 자원을 요구할 때 가진 자원을 빼앗을 수 있게 합니다.
순환대기 부정 : 자원에 고유번호 할당 후 순서대로 자원을 요구하도록 합니다
회피
는 교착 상태가 발생할 가능성을 배제하지 않고, 교착 상태가 발생하면 적절히 피해 나가는 방법입니다.(데드락 가능성이 없을때만 자원할당)
대표적인 예로 은행원 알고리즘이 있습니다.(자원을 요청할때마다 회피 알고리즘을 사용하면 오버헤드가 커서 현실성은 X)
탐지 및 회복 방법
은 교착 상태가 되도록 허용한 다음 회복시키는 방법입니다.자원 할당 그래프를 모니터링(cycle 여부 조사)하면서 교착 상태가 발생하는지 살펴보고, 발생 시 회복 단계가 진행됩니다.
회복 시에는 교착 상태의 프로세스를 모두 중지하거나 교착 상태가 제거될 떄 까지 하나씩 프로세스를 중지하는 방법을 사용합니다.
또는 교착상태의 프로세스가 점유하고 있는 자원을 빼앗아 다른 프로세스에게 할당해줍니다.
무시는 OS가 데드락에 관여 안하고 사용자가 알아서 프로세스를 죽이도록 하는 방식으로 현재 대부분의 OS가 채택하고 있습니다.
데드락은 빈번히 발생하는 이벤트가 아니기 때문에 많은 오버헤드 비용이 생기는 기존의 방식을 개선한 방식입니다.
참고 - 데드락 조건인 순환대기는 자원할당 그래프 상에서 cycle을 형성함으로써 발생. 사이클이 존재한다면 교착 상태 가능성을 나타냄.
꼬리질문 - 은행원 알고리즘이 무엇인지 설명해주세요.
은행원 알고리즘은 은행에서 모든 고객의 요구가 충족되도록 현금을 할당하는데서 유래하였습니다. 프로세스가 자원을 요구할 때, 시스템은 자원을 할당한 후에도 안정 상태로 남아있게 되는지 사전에 검사하여 교착상태 회피하는 방법으로
안정 상태라면 자원을 할당하고, 아니면 다른 프로세스들이 자원을 해지할때 까지 기다리는 알고리즘입니다(아니면 요구가 만족될때 까지 거절).
여기서 안정 상태란 시스템이 교착 상태를 일으키지 않으면서 각 프로세스가 요구한 최대 요구량만큼 필요한 자원을 할당 해줄 수 있는 상태를 뜻합니다.
메모리 및 가상 메모리 관련 질문
기준 레지스터와 한계 레지스터가 무엇인지 설명하고, 이들을 어떻게 이용해 메모리 보호를 수행하는지 설명해주세요(ex: 영역 밖에 접근하려할때).
기준 레지스터와 한계 레지스터는 운영체제의 메모리 보호 방법에 사용되는 두 가지 레지스터입니다.
기준 레지스터는 프로그램이 접근할 수 있는 메모리 상의 가장 작은 주소를 저장하고, 한계 레지스터는 그 프로그램이 기준 레지스터 값부터 접근할 수 있는 메모리의 범위를 보관하고 있습니다. 따라서 프로그램은 기준 레지스터의 주소부터 기준 레지스터의 값과 한계 레지스터 값을 더한 주소 사이의 영역에만 접근할 수 있습니다. 만약 이 범위를 넘어서는 메모리 영역에 접근하려고 하면, 운영체제는 예외 상황으로 처리하고, 프로그램을 강제 종료시키는 등의 처리를 합니다.
이렇게 하면, 프로그램이 메모리의 허가되지 않은 영역, 예를 들어 다른 프로그램이나 운영체제가 위치하는 영역 등에 침범하는 것을 방지할 수 있습니다. 다만 이 방법은 프로그램이 메모리의 한 영역에 연속적으로 위치할 경우에만 사용할 수 있습니다.
참고
그리고 메모리 접근 명령 자체는 특권 명령이 아니지만, 기준 레지스터와 한계 레지스터의 값을 설정하는 연산은 특권 명령입니다. 그래서 운영체제만이 기준 레지스터와 한계 레지스터 값을 변경할 수 있고, 사용자 프로그램은 이 값들을 변경할 수 없습니다. 이렇게 함으로써 보안을 유지할 수 있습니다.
물리적 주소와 논리적 주소(가상 주소)의 차이는 무엇인가요?
가상 주소는 프로세스의 관점에서 볼때의 메모리 주소로, 프로세스가 메모리를 참조할 때 사용하는 주소입니다.
이러한 주소는 프로세스가 생성될 때 부터 시작되며, 0번지 부터 시작됩니다.
반면 물리적 주소는 실제 시스템 메모리에서 데이터가 위치한 주소를 의미합니다. 주소 바인딩 과정(MMU가 진행)을 통해 논리적 주소는 물리적 주소로 변환됩니다.
참고 - 동일한 가상 주소 값이 더라도 각 프로세스마다 서로 다른 내용을 담고 있다.
동적 로딩과 스와핑에 대해 아시나요?
동적 로딩(주로 다중 프로그래밍 상황에서)이란 프로세스가 시작될 때, 그 프로세스의 주소 공간 전체를 메모리에 올려 놓는 것이 아니라, 해당 부분이 불릴때 그 부분만을 메모리에 적재하는 방식입니다.
그리고 스와핑은 메모리에 올라온 프로세스의 주소 공간 전체를 디스크의 스왑영역에 일시적으로 내려놓는 것을 말합니다.
(종료가 아닌 특정 이유로 인해, ex: 너무 많은 프로그램이 메모리에 동시에 올라와 성능이 떨어지는 경우 막기 위해)
참고 - 그냥 링킹은 개발자가 작성한 소스 코드를 컴파일하여 생성된 목적 파일과 이미 컴파일된 라이브러리 파일을 묶어 하나의 실행파일을 생성하는 과정
참고 - 동적 linking(연결)이란 컴파일을 통해 생성된 파일과 라이브러리 파일 사이의 연결을 프로그램 실행 시점까지 지연시키는 기법입니다.
이때 실행 파일의 라이브러리 호출 부분에 스텁이라는 작은 코드를 두고, 라이브러리 호출시 스텁을 통해 해당 라이브러리가 메모리에 존재하는지 살펴보고, 존재한다면 메모리 위치를 직접 참조하고, 그렇지 않은 경우엔 디스크에서 라이브러리 파일을 찾아 메모리에 적재 후 수행하는 것입니다.
외부 단편화와 내부 단편화에 대해 설명해주세요(Fragmentation)
외부 단편화란 여러 프로세스들이 메모리에 할당되고 해제되는 과정에서 남은 메모리 조각들이 프로세스에 필요한 공간보다 작아 사용하지 못하는 상황을 말합니다.
이 문제는 메모리 공간이 충분하더라도 연속적이지 않은 여러 공간으로 나뉘어져 있어 원하는 크기의 메모리를 할당받을 수 없는 상황을 초래합니다.
내부 단편화는 할당된 메모리 블록 내에서 프로세스가 실제로 사용하지 않는 메모리가 남아있는 상황을 말합니다.
예를들어 프로세스가 100바이트의 메모리를 필요로 하지만, 시스템이 128바이트 블록을 할당하면, 28바이트는 사용되지 않고 남아 내부 단편화를 초래합니다.
외부 단편화 - 컴팩션으로 해결가능
컴팩션이란 메모리 내의 모든 프로세스들을 재배치하여 메모리 공간을 연속적으로 만드는 것
외부 단편화 이해 예시
예를 들어, 우리가 가지고 있는 메모리가 1,000바이트라고 가정합시다. 이 때, 첫 번째 프로세스가 200바이트를 필요로 하므로 운영 체제는 이 프로세스에게 첫 200바이트를 할당합니다. 이어서 두 번째 프로세스가 300바이트를 필요로 하면, 이 프로세스는 다음의 300바이트(즉, 201-500바이트)를 할당받습니다. 그런 다음 세 번째 프로세스가 400바이트를 요구하면, 그것은 다음의 400바이트(즉, 501-900바이트)를 할당받습니다.
이 상태에서 첫 번째 프로세스와 두 번째 프로세스가 종료되어 해당 메모리를 반납하게 되면, 500바이트(1-200바이트와 201-500바이트)의 메모리가 사용 가능해집니다. 이 시점에서 새로운 프로세스가 400바이트의 메모리를 요청하면, 운영 체제는 충분한 메모리가 있다고 판단하고 이를 할당하려고 할 수 있습니다.
그러나 문제는 이 500바이트가 연속적인 블록이 아니라 200바이트와 300바이트 두 개의 분리된 블록으로 존재한다는 것입니다. 만약 새로운 프로세스가 400바이트의 연속적인 메모리를 필요로 한다면, 이 프로세스는 메모리를 할당받지 못하게 됩니다. 이렇게 충분한 메모리가 있음에도 불구하고 연속적이지 않은 메모리 공간 때문에 메모리를 할당받지 못하는 상황이 바로 외부 단편화를 의미합니다.
연속 메모리 할당에서 고정 분할 방식과 가변 분할 방식에 대해 설명해주세요.
연속 할당 방식은 각각의 프로세스를 물리적 메모리의 연속적인 공간에 올리는 방식으로 고정 분할과 가변 분할 총 두가기에 방식이 있습니다.
고정 분할 방식은 물리적 메모리를 정해진 개수 만큼의 영구적인 분할로 나누어 두고, 각 분할에 하나의 프로세스를 적재하는 방식입니다.
이는 프로세스를 분할된 메모리에 할당하는 과정에서 내부/외부 단편화가 발생할 수 있습니다.
가변 분할 방식은 프로세스가 필요한 만큼 메모리를 동적으로 할당하는 방식입니다.
프로세스에 딱 맞게 메모리 공간을 사용하기 때문에 내부 단편화는 발생하지 않지만, 프로세스의 할당 및 해제가 반복되면 사용가능한 메모리 공간이 흩어져 외부 단편화가 발생할 수 있습니다.
이러한 외부 단편화를 해결하기 위해 흩어진 메모리 공간을 한쪽으로 몰고 가용 공간을 확보하는 컴팩션이라는 방법이 있으나 overhead가 많이 발생하는 단점이 있습니다.
추가 내용 - 불연속할당은 하나의 프로세스를 여러 물리적 메모리에 나누어 적재하는 방법이며 페이징, 세그먼테이션, 페이지드 세그먼테이션 기법 등이 있습니다
가변 분할 방식에서는 프로세스를 메모리에 올릴때 물리적 메모리 내 가용 공간중 어떤 위치에 올릴것인지 다루어야 함(동적 메모리 할당 문제)
연속할당과 불연속할당의 차이를 설명해주세요.(읽어만 보기)
A) 메모리의 낮은 주소 영역엔 커널이 상주해있고 메모리의 높은 주소 영역엔 사용자 프로그램이 올라가게 됩니다. 이때 사용자 프로그램을 할당하는 방식에 따라 연속할당과 불연속할당으로 나눌 수 있습니다.
연속할당은 다시 고정 분할 방식과 가변 분할 방식으로 나뉩니다. 고정 분할 방식은 물리적메모리를 미리 몇 개의 분할로 나누어 그 곳에 프로그램을 적재하는 방식입니다. 이 방법은 내부, 외부 조각이 모두 발생할 수 있습니다. 가변 분할 방식은 프로그램 크기를 고려하여 분할의 크기와 개수가 동적으로 변하는 방식입니다. 이 방법은 외부조각이 발생할 수 있으며 프로그램을 어느 홀에 적재시킬지 결정하는 문제가 추가로 발생합니다.
불연속할당은 하나의 프로세스를 여러 물리적 메모리에 나누어 적재하는 방법이며 페이징, 세그먼테이션, 페이지드 세그먼테이션 기법 등이 있습니다.
가변 분할 방식에서의 메모리 배치 전략을 설명해주세요.
우선 최초적합(First Fit) 방법은 충분한 크기를 가진 첫번째 메모리 공간에 프로세스를 할당하는 방식입니다.
이는 간단하고 overhead가 적게 발생하나 공간 활용률이 떨어질수 있습니다.
최적 적합(Best Fit)는 프로세스가 할당될 수 있는 공간 중 가장 작은 곳을 선택하는 방식입니다.
모든 메모리 공간을 탐색하기에 overhead가 많이 발생합니다. 크기가 큰 공간을 유지할 수 있으나 활용하기 어려운 작은 크기의 공간이 많이 발생합니다.
최악 적합(Worst Fit)은 프로세스가 할당되어 있는 메모리 공간 중 가장 큰 곳을 선택한 방식입니다.
이는 모든 메모리 공간을 탐색하기에 overhead가 크며, 활용하기 어려운 작은 크기의 공간이 생기는 것을 방지할 수 있지만, 큰 크기의 메모리 공간 확보가 어렵습니다.
페이징 기법이란 무엇인가요??(외부 단편화 해소 기법)
페이징 기법이란 프로그램(or 프로세스 주소 공간 or 가상 메모리)을 동일한 크기의 페이지 단위로 나누고 물리적 메모리도 동일 크기의 프레임으로 나눈 뒤 이 곳에 페이지를 적재하는 기법입니다.
이러한 페이징 기법에서는 하나의 프로세스라 하더라도 페이지 단위로 물리적 메모리에 올리는 위치가 달라져 모든 프로세스가 각각의 주소변환을 위한 페이지 테이블을 가지게 됩니다
MMU(CPU와 물리 메모리 사이 위치 하드웨어)가 주소 변환을 위해 페이지 번호와 페이지 오프셋을 사용하여 물리적 주소의 위치를 알아냅니다. 페이지 번호를 인덱스로하여 페이지 테이블 접근 시 프로세스의 물리적 메모리 상 시작 위치를 얻고, 이 값에 오프셋을 더함으로써 (논리적 주소에 대응하는) 물리적 주소를 얻을 수 있습니다.
이러한 주소 변환 과정에서 페이지 테이블에 접근하고, 실제 데이터에 접근하는 두번의 메모리 접근이 필요해, 이때 테이블 접근 오버헤드를 줄이기 위해 TLB라는 하드웨어가 사용되기도 합니다.
여기서 TLB는 빈번히 참조되는 페이지에 대한 주소 변환 정보만을 담게 됩니다.
이러한 페이징 기법을 활용하면 프로세스의 전체 주소 공간을 물리적 메모리에 한번에 올릴 필요가 없다는 장점을 가집니다. 필요에 다라 각 페이지는 개별적으로 메모리에 로드되거나, 보조 저장장치 (ex: 디스크, 백킹 스토어)에 저장될 수 있습니다.
이를 통해 메모리 관리가 유연하고 효율적으로 이루어집니다.
꼬리질문 - 페이징 기법에서 단편화 현상이 발생하나요?
페이징 기법에서는 프로세스를 동일한 크기의 페이지로 분할하고, 메모리도 같은 크기의 프레임으로 분할하므로 어떤 프레임에도 어떤 페이지가 할당될 수 있어 외부 단편화는 발생하지 않습니다.
하지만 페이지 단위로 메모리를 할당하게 되면 마지막 페이지에서 프로세스가 모든 공간을 사용하지 않는 경우 내부 단편화가 발생할 수 있습니다.
예를 들어, 페이지 크기가 4KB라고 가정하겠습니다. 만약 10KB 크기의 프로세스가 메모리에 로드된다면, 이는 세 개의 페이지 (4KB, 4KB, 2KB)로 분할됩니다. 여기서 마지막 2KB 페이지는 그 페이지의 나머지 2KB가 사용되지 않는 상태로 남아 있게 되므로, 이는 내부 단편화의 예시가 됩니다
꼬리질문 2 - TLB가 무엇이죠?
TLB(Translation Lookaside Buffer)는 하드웨어 캐시로서, 가장 최근에 참조된 페이지 번호와 해당 페이지의 물리 주소를 저장합니다. 페이지 주소 변환 요청이 있을 때, 먼저 TLB를 확인하여 빠르게 변환 정보를 얻을 수 있습니다. 만약 TLB에 해당 정보가 없다면 페이지 테이블을 참조하게 됩니다
꼬리질문 3 - 페이징 기법을 사용하면 어떤 장단점이 있나요?
페이징 기법의 장점으로는 메모리 관리의 유연성이 있습니다. 프로세스 전체를 메모리에 적재하지 않고 필요한 부분만 로드하여 메모리 사용을 최적화할 수 있습니다.
단점으로는 페이지 테이블 관리에 따른 오버헤드와 페이지 교체 알고리즘에 따른 복잡성이 있을 수 있습니다.
참고 - CPU가 생성한 논리주소를 MMU에 전달함
페이지 테이블은 주 메모리에 위치하고, MMU에 의해 관리됨
페이지 테이블에는 번호 오프셋 빼고 보호비트(각 페이지 접근 권한)와 유효 무효 비트(해당 페이지 내용이 유효한지)를 둠
TLB를 두면 페이지 테이블을 건너뛰고 바로 물리 주소 변환 정보를 얻을 수 있다.
하지만 모든 주소 변환이 TLB에 저장되지 않기에 TLB 미스가 발생할 경우엔 다시 페이지 테이블을 참조해야 함.
페이징도 가상 메모리 관리 방식임
세그멘테이션 기법에 대해 설명해주세요.
세그멘테이션이란 프로그램을(프로세스의 주소 공간을) 의미 단위인 세그먼트로 나누어 물리적 메모리에 올리는 기법입니다.
세그멘테이션 기법에서 주소 변환 과정은 페이징 기법과 유사하나 세그멘테이션 기법의 경우 세그먼트 크기가 각각 다르기 때문에 세그먼트 테이블에는 세그먼트 번호에 따른 시작 주소(베이스)뿐만 아니라, 리미트(길이)정보가 담겨있습니다.
이때 오프셋 값이 세그먼트의 리미트를 넘어서는 경우에는 잘못된 주소로 판단하고 시스템이 예외를 발생시킵니다.
그렇지 않다면 베이스 값과 오프셋 값을 사용하여 물리적 주소의 위치를 알아냅니다.
이러한 세그먼트 방식은 의미 단위로 나누어져 있기 때문에 공유와 보안의 측면에서 페이징 기법에 비해 훨씬 효과적입니다. 예를 들어 페이지 기법에서 동일한 크기로 주소 공간을 나누다 보면 공유하려는 코드와 사유 데이터 영역이 동일 페이지에 공존하는 경우가 발생할 수 있습니다.
반면 세그멘테이션 기법에서는 이러현 현상이 발생하지 않으므로 공유나 보안처럼 의미 있는 단위에 대해 수행하는 업무에서는 페이징 기법보다 세그멘테이션 기법이 장점을 가집니다.
하지만 세그멘테이션 방식은 세그먼트의 크기가 균일하지 않기 때문에 메모리 관리에서 외부 조각이 발생하게 되며, 어떤 가용 공간에 세그먼트를 할당할 것인지 결정하는 문제가 생깁니다.
이 문제는 가변 분할 방식에서 발생하는 문제와 유사하여, 최초 적합 또는 최적 적합과 같은 방식을 사용해 해결할 수 있습니다.
꼬리질문 1 - 세그멘테이션에서 외부 단편화가 발생할 수 있나요?
세그멘테이션 기법에서는 각 세그먼트의 크기가 다르기 때문에 메모리를 할당하고 해제하는 과정에서 이러한 외부 조각이 발생할 수 있습니다.
꼬리질문 2 - 세그멘테이션 기법에서는 어떻게 메모리 보호를 구현하나요?
세그멘테이션 기법에서는 세그먼트 테이블의 각 항목에 보호비트와 유효비트를 둠으로써 메모리 보호를 구현합니다. 보호 비트는 각 세그먼트에 대해 읽기, 쓰기, 실행 등의 권한이 있는지를 나타내며, 유효비트는 해당 세그먼트의 주소 변환 정보가 유효한지, 즉 해당 세그먼트가 현재 물리적 메모리에 적재되어 있는지를 나타냅니다.
꼬리질문 3 - 페이지 세그멘테이션에 대해 아시나요?
페이지드 세그멘테이션 방법은 페이징과 세그멘테이션이라는 두가지 메모리 관리 기법을 결합한 것입니다.
세그먼테이션 기법과 마찬가지로 프로세스를 여러 개의 세그먼트로 나누지만 이때 세그먼트 들이 임의의 길이를 가질 수 있는 것이 아니라 반드시 동일한 크기 페이지들의 집합으로 구성되어야 합니다.
즉 페이지드 세그먼테이션 기법에서는 하나의 세그먼트 크기를 페이지 크기의 배수가 되도록 함으로써 세그먼테이션 기법에서 발생하는 외부 조각 문제점을 해결하는 동시에 세그먼트 단위로 프로세스 간의 공유나 프로세스 내의 접근권한 보호가 이루어지도록 함으로써 페이징 기법의 약점을 해소합니다.
가정해봅시다. 페이지의 크기를 4KB로 정하고, 우리가 두 개의 세그먼트를 가진 프로세스를 메모리에 로드하려고 합니다. 이때 하나의 세그먼트는 7KB이고, 다른 하나는 13KB라고 가정해봅시다.
페이지드 세그멘테이션 기법에서는 각 세그먼트가 페이지 크기의 배수가 되도록 만듭니다. 따라서 첫 번째 세그먼트는 4KB 페이지 2개로 분할되며, 두 번째 세그먼트는 4KB 페이지 4개로 분할됩니다. 이렇게 되면, 우리는 세그먼트를 각각 8KB와 16KB로 취급할 수 있습니다. 이는 페이지의 크기(4KB)의 배수이며, 따라서 세그멘테이션 기법에서 발생하는 외부 조각 문제를 해결합니다.
어떤 경우 세그멘테이션 어떤 경우 페이징 - 공유와 보안이 중요한 경우에는 세그멘테이션 기법을, 메모리의 효율적인 활용과 쉬운 관리가 중요한 경우에는 페이징 기법을 선호
가상 메모리에 대해 설명해주세요.
가상 메모리란 실제 물리적 메모리의 크기를 초과하는 프로그램의 실행을 가능하게 하는 기법입니다.
가상 메모리는 필요한 부분만을 실제 물리적 메모리에 올려 사용하고, 나머지 부분은 하드 디스크와 같은 저장 장치에 임시로 저장해둡니다. 이렇게 함으로써 더 큰 양의 메모리를 가지고 있는 것처럼 동작하게 됩니다.
가상 메모리는 프로세스가 필요로 하는 페이지가 실제 메모리에 없는 경우, 즉 페이지 폴트가 발생하면, 이를 하드웨어로 부터 가져오는 I/O 작업이 발생하기에 성능 저하의 요인이 될 수 있습니다.
이때 효율적인 페이지 교체 알고리즘을 사용하면 페이지 폴트 빈도를 줄일 수 있습니다.
참고
OS는 프로세스들의 내용(페이지) 중에서 덜 중요한 것들을 하드디스크에 옮겨 놓고, 관련 정보를 페이지 테이블에 기록합니다. CPU는 프로세스를 실행하면서 페이지 테이블을 통해 페이지를 조회하는데, 실제메모리에 원하는 페이지가 없는 상황이 발생할 수 있습니다(Valid bit를 통해 확인)
가상 메모리는 프로세스들이 독립적인 메모리 공간을 갖는 것처럼 느끼게 하여, 프로세스 간의 메모리 보호와 독립성을 제공하는 데도 중요한 역할을 합니다.
페이지 교체 알고리즘이란 운영 체제에서 가상 메모리를 관리하는 방법 중 하나로, 물리적 메모리가 가득 찬 상황에서 새로운 페이지를 메모리에 로드해야 할 때 어떤 페이지를 교체해야 하는지 결정하는 방법을 정의합니다.
가상 메모리 방식은 보통 요구 페이징 방식으로 구현됨
요구페이징이 무엇이죠?
요구 페이징이란 프로그램 실행 시 프로세스를 구성하는 모든 페이지를 한꺼번에 올리는 것이 아니라, 당장 사용될 페이지만 메모리에 올리는 방식을 말합니다.
이러한 요구 페이징은 당장 필요한 페이지만을 메모리에 적재하기에 메모리 사용량이 감소합니다.
각 페이지가 메모리가 존재하는지 판단하기 위해 요구 페이징에서 유효-무효 비트를 표시하게 되며, 이는 페이지 테이블에 저장되어있습니다.
만약 CPU가 현재 참조하려는 페이지가 메모리에 있지 않다면 페이지 폴트가 발생하고, 이때 운영체제가 페이지 폴트 처리루틴을 거쳐 해당 페이지를 메모리에 적재하게 됩니다.
1이면 해당 페이지가 메모리에 존재, 0이면 안존재
페이지 폴트가 무엇인지랑 처리 과정에 대해 설명해주세요.
페이지 폴트란 CPU가 참조하려는 페이지가 물리적 메모리에 없는 상황을 말합니다. 이때 페이지 폴트 예외를 발생시키며, 이를 처리하기 위해 페이지 폴트 처리 루틴이 호출됩니다.
프로세스가 실행되면서 CPU가 특정 페이지에 접근하려할때, 먼저 해당 페이지가 메인 메모리에 있는지 확인해야합니다.
이는 페이지 테이블에서 해당 페이지의 Valid bit를 확인함으로써 이루어지고, valid bit가 1이면 해당 페이지는 메모리에 존재하므로 CPU는 메모리에서 해당 페이지를 참조하여 연산을 수행합니다.
만약 valid bit가 0, 즉 invalid 상태라면 MMU는 페이지 폴트 예외(페이지 폴트 트랩)를 발생시킵니다.
그러면 커널모드로 전환되고, 운영체제의 페이지 처리 루틴이 호출됩니다. 이때 운영체제는 invalid한 경우가 메모리 경계를 넘는 것이나, 페이지에 대한 접근 권한을 위반한 경우엔 해당 프로세스를 종료시키고, 페이지 폴트라면 free frame을 할당받습니다.
이때 만약 free frame이 없다면 페이지 교체 알고리즘을 바탕으로 swap out을 진행합니다.
할당 받은 프레임에 페이지를 로드하기 위해 운영체제는 디스크에 I/O 요청을 하고, 페이지 부재를 발생시킨 프로세스는 CPU를 빼앗기고 봉쇄상태가 됩니다. 이때 PCB에 레지스터 상태 및 PC값을 저장함으로서 나중에 다시 CPU를 할당받았을 때 같은 상태에서 명령을 수행할 수 있습니다.
이후 디스크에서 I/O가 완료되어 인터럽트가 발생하면 해당 페이지를 메모리에 적재하고, 페이지 테이블에서 해당 페이지의 비트를 valid(1)로 설정합니다.그리고 봉쇄 상태에 있던 프로세스를 ready 상태로 변경 시켜 준비 큐로 이동시킵니다.
이후 이 프로세스가 다시 CPU를 할당받으면 PCB에 저장되어있던 값을 복원시켜 이전에 중단되었던 명령부터 실행을 재개합니다.
꼬리 질문 1 - 페이지 폴트 발생 빈도를 줄이기 위해서는 어떻게해야할까요??
서비스의 특성에 맞게 효과적인 페이지 교체 알고리즘을 선택하거나 페이지 크기를 적절히 선택함으로서 페이지 폴트 발생 빈도를 줄일 수 있습니다.
그리고 메모리의 크기를 증가시키거나, 프로그램 코드를 최적화하여 자주 사용되는 데이터가 같은 페이지에 위치하도록 하는 방법도 있습니다.
페이지가 너무 작으면 페이지 테이블이 커져 메모리 사용이 늘어나고, 페이지 폴트 빈도가 증가할 수 있습니다(한번에 로드할 수 있는 데이터 양이 적음, 공간지역성도 고려). 반대로 페이지가 너무 크면 내부 조각화 문제가 발생할 수 있습니다
페이징 교체 알고리즘이 무엇인지랑 종류에 대해 설명해주세요.
페이징 교체 알고리즘이란 물리적 메모리가 가득 찬 상황에서 새로운 페이지를 메모리에 로드해야 할 때 어떤 페이지를 교체해야 하는지 결정하는 방법입니다.
우선 선입선출 알고리즘(FIFO)은 페이지 교체시 물리적 메모리에 가장 먼저 올라온 페이지를 우선적으로 내쫓는 방식입니다.
이는 페이지의 향후 참조 가능성을 고려하지 않기에 가장 먼저 메모리에 들어온 페이지가 계속해서 많은 참조가 이어지더라도 내쫓기게 됩니다.
그리고 FIFO 알고리즘에서는 페이지 프레임 수를 증가 시켰음에도 페이지 부재가 더 많이 발생하는 이상현상 또한 발생할 수 있습니다.
Optimal 알고리즘은 가장 먼 미래에 참조되는 페이지를 내보내는 알고리즘입니다. 이 알고리즘은 미래에 참조될 페이지를 모두 알고 있다고 가정하는 알고리즘이라 현실적으로 구현에 어려움이 있습니다.
따라서 이는 보통 다름 알고리즘 성능의 상한선을 제공하는 역할을 하게 됩니다.
LRU(Least Recently Used) 페이지 교체 알고리즘은 가장 오랫동안 사용되지 않은 페이지를 교체하는 방식입니다.
프로그램은 보통 지역성 원칙에 따라 실행됩니다. 즉 특정 시간 동안 특정 부분을 집중적으로 참조하는 경향이 있습니다(시간 지역성).
LRU 알고리즘은 이런 지역성 원칙을 활용하여 페이지 폴트 발생 확률을 감소시킨다는 장점이 있지만, 페이지 교체를 위해 페이지마다 사용된 시간을 기록해야 하기에 추가적인 메모리 공간이 필요합니다.(참조 횟수 고려 안함)
LFU(Least Frequently Used) 페이지 교체 알고리즘은 가장 적게 사용된 페이지를 교체하는 방식입니다.(이 또한 지역성을 따름)
이는 자주 사용되지 않는 페이지를 교체함으로서 메모리를 효율적으로 사용한다는 장점이 있지만, 페이지 사용횟수를 기록하기 위해 추가적인 메모리 공간이 필요하고
처음에 자주 참조되던 페이지가 이후에는 거의 참조되지 않더라도, 초기에 높았던 참조 횟수때문에 메모리에 계속 유지될 수 있습니다. 즉 시간에 따른 페이지 참조변화를 반영하지 못합니다.
NUR(Not Used Recently)는 LRU와 유사한 알고리즘으로, 최근에 사용하지 않은 페이지를 교체하는 방식입니다.
LRU 알고리즘은 가장 오래전에 참조된 페이지를 교체하는 것에 비해 NUR는 오랫동안 사용하지 않은 페이지중 하나를 교체합니다.즉 교체되는 페이지의 참조시점이 가장 오래되었다는 것을 보장하지 못합니다.
최근 참조 여부를 확인하기 위해 각 페이지 마다 참조 비트(참조되지 않은 경우 0, 참조된경우 1)와 변형 비트(페이지 내용 변경 X : 0, 변경 시 1)를 둡니다.
동작 방식에 대해 간단히 설명드리자면 운영체제가 일정 시간 간격으로 모든 페이지의 참조 비트를 검사하고, 이를 0으로 리셋합니다.이는 최근에 참조된 페이지를 판별하기 위해 진행되는 과정입니다.
그리고 페이지가 참조될 때마다 참조 비트를 1로, 페이지가 수정될때마다 변형비트가 1로 설정됩니다.
페이지 교체가 필요할때 운영체제는 두 비트 모두를 고려하여 교체 페이지를 선정합니다.이때 참조와 변형 비트가 둘다 0인 페이지가 최우선적으로 교체 대상이 되고,
만약 그런 페이지가 없다면 참조0,변형1 참조1,변형0, 참조1 변형 1 순서로 검색을 진행하여 교체 대상을 찾습니다.
꼬리질문 1 - NUR는 변형 비트를 왜 사용할까??
페이지를 디스크로 내릴 때 해당 페이지가 수정되었는지 아닌지 알면 효율성을 높일 수 있습니다.
만약 페이지가 수정되지 않았다면 디스크에 이미 같은 내용의 페이지가 있을테니, 페이지를 디스크에 쓰지 않고 그냥 무시할 수 있습니다.
반면 페이지가 수정된 경우에만 디스크에 쓰는 작업을 수행하면 됩니다. 이러한 방식으로 I/O 연산을 줄여 시스템 성능을 향상시킬 수 있습니다.
꼬리질문 2 - NUR이 LRU, LFU에 비해 어떤 장점을 가지는가?
LRU,LFU의 경우엔 각 페이지에 대한 메타데이터(참조에 대한 상세한 정뷰 유지 및 추적)를 유지(페이지가 언제 마지막으로 참조되었는지,페이지가 얼마나 자주 참조되었는지) 및 추적해야 하는 반면
NUR 알고리즘은 2bit만 추가하여 LRU,LFU과 유사한 성능을 낼 뿐만아니라 쉽게 구현할 수 있다는 장점을 가집니다.
스레싱(thrashing)이 무엇인가요??
(스레싱이란 할당받은 페이지 프레임의 크기가 작아서(프로세스가 너무 많이 올라와 있어서), 집중적으로 참조되는 페이지들의 집합을 메모리에 한꺼번에 적재하지 못하면서 페이지 폴트가 자주발생하고, 이에 따라 CPU 이용률이 급격이 떨어지는 상태를 말합니다.)
즉 스레싱은 페이지 폴트가 과도하게 발생하여 CPU가 실제 연산을 수행하기보다는 페이지를 교체하는 데 대부분의 시간을 소비하는 현상을 의미합니다. 이는 실제 메모리에 적재되어 있어야 할 페이지들이 대부분 디스크에 존재하므로 발생합니다.
이러한 스레싱은 어떻게 해결할까요?
우선 메모리에 동시에 올라와 있는 프로세스를 수를 제한하여, 각 프로세스가 사용할 수 있는 메모리 공간을 증가시키는 것으로 해결할 수 있습니다.
이를 통해 각 프로세스가 필요로 하는 페이지를 더 많이 메모리에 로드할 수 있을 것입니다.
그리고 효율적인 페이지 교체 알고리즘을 사용하여 페이지 폴트 빈도를 줄이거나, 가능하다면 물리적 메모리 용량을 증가시킴으로서도 해결 할 수 있습니다(스레싱 발생 지점 늦춤).
CPU 스케줄링, 가상 메모리를 통해서도 가능
참고
워킹셋 알고리즘은 지역성 집합(자주 참조되는 페이지 집합)이 메모리에 동시에 올라갈 수 있도록 보장하는 메모리 관리 알고리즘이며,
여기서 워킹셋이란 프로세스의 원할한 수행을 위해 한꺼번에 메모리에 올라와야 하는 페이지들의 집합을 말합니다. 이는 워킹셋을 구성하는 페이지들이 한꺼번에 메모리에 올라갈 수 있는 경우에만 그 프로세스에게 메모리를 할당하고, 그렇지 않은 경우엔 프로세스에게 할당된 페이지 프레임을 모두 반납시킨 후 그 프로세스의 주소 공간 전체를 디스크로 스왑아웃 시키는 방식으로 동작합니다.
페이지 부재 빈도 알고리즘(PFF)는 프로세스의 페이지 부재율을 주기적으로 조사하고, 이 값에 근거해서 각 프로세스에 할당할 메모리 양을 동적으로 조절하는 알고리즘입니다.
만약 어떤 프로세스의 페이지 부재율이 시스템에서 미리 정해둔 상한 값을 넘게된다면, 이 프로세스에게 프레임을 추가로 더 할당하고, 하한 값 이하로 떨어진다면 필요 이상의 많은 프레임이 할당된 것으로 간주해 프레임의 수를 줄이게 됩니다!
디스크 관련 질문
디스크 스케줄링이 무엇이고 종류에 대해 설명해주세요.
디스크 스케줄링이란 운영체제에서 디스크 I/O 요청들을 어떤 순서로 처리할지 결정하는 알고리즘을 의미하고, 디스크 헤드의 이동 거리를 최소화 하는 것이 주 목적입니다.
우선 FCFS 스케줄링은 디스크에 먼저 들어온 요청을 먼저 처리하는 방식으로 동작합니다.
이는 입출력 요청이 한쪽 끝과 반대쪽 끝에 번갈아 도착한다면, 디스크가 계속 왕복해야 하기에 탐색 시간이 매우 길어질 수 있습니다.
SSTF(Shortest Seek Time First) 스케줄링은 헤드의 현재 위치로부터 가장 가까운 위치에 있는 요청을 제일 먼저 처리하는 방식입니다.
이때는 starvation 문제가 발생할 수 있습니다(ex : 가까운 곳에 요청만 지속적으로 올경우 먼 곳에 떨어진 요청은 무한히 기다려야 하는 상태 될수도).
SCAN은 디스크의 안쪽 끝과 바깥쪽 끝을 오가며, 그 경로에 존재하는 모든 요청을 처리하는 방식입니다.(엘리베이터와 유사)
이러한 SCAN 방식은 FCFS처럼 불필요한 헤드의 이동이 발생하거나, SSTF처럼 일부 지역이 지나치게 오래 기다리는 현상이 발생하지 않으나, 헤드가 가운데 위치를 지나가는 주기가 양끝을 지나가는 주기의 절반에 불과하기에 기다리는 시간이 공평하지 않을 수 있습니다.
이를 해결하기 위해 생겨난 알고리즘이 C-SCAN 알고리즘입니다. 이는 SCAN 처럼 헤드가 한쪽 끝에서 다른 쪽 끝으로 이동하며 가는 길목에 모든 요청을 처리하지만,
스캔과 달리 헤드가 다른쪽 끝에 도달해 방향을 바꾼 후에는 요청을 처리하지 않고 곧바로 출발점으로 이동합니다.(SCAN 보다 균일한 탐색시간)
LOOK 알고리즘은 SCAN 알고리즘을 개선한 방법으로 헤드가 한쪽 방향으로 이동하다가, 그 방향에 더 이상 대기 중인 요청이 없으면 헤드의 이동 방향을 즉시 반대로 바꾸는 스케줄링 방식입니다.
C-LOOK 알고리즘은 전방에 요청이 없을때 방향을 바꾼다는 측면에서 Look과 유사하지만, 한쪽 방향으로 이동할때만 요청을 처리한다는 점에서 차이를 보입니다.
ex) 예를들어 왼쪽끝에서 오른쪽 끝으로 이동할때만 요청 처리, 요청 처리후 디스크 헤드는 다시 왼쪽 끝으로 이돌아감(이때 요청을 처리하지 않음)
참고 - 디스크 헤드의 이동거리 과정
디스크는 데이터를 저장하는 매체인 플래터(Platter)와, 데이터를 읽고 쓰는 장치인 헤드(Head)로 구성되어 있습니다. 디스크에서 데이터를 읽거나 쓰려면 디스크 헤드가 해당 데이터가 위치한 트랙(Track)에 도달해야 합니다
디스크 헤드의 이동 거리를 최소화한다는 것은, 디스크 헤드가 데이터에 접근하기 위해 플래터 위에서 움직이는 거리를 줄이는 것을 의미합니다. 디스크 헤드의 이동 (Seek)은 디스크 I/O 작업에서 가장 시간이 많이 소요되는 부분이기 때문에, 이 이동 거리를 최소화함으로써 전체적인 디스크 I/O 성능을 향상시킬 수 있습니다.
RAID에 대해 설명해주세요. RAID 0 과 1의 차이점은 뭐죠?
RAID(Redundant Arrays of Inexpensive Disks)란 디스크를 자동으로 백업하고, 장애가 발생하면 복구하는 시스템입니다.
RAID 0은 디스크를 병렬로 연결하여 데이터를 여러 개의 디스크에 빠르게 저장하고 가져올 수 있는 방법입니다.
RAID 1은 같은 데이터를 2개의 디스크에 저장(미러링)하여 문제가 생겼을때 복구할 수 있도록 하는 방법입니다.
RAID3의 단점을 5,6에서 어떤식으로 단점을 극복했죠?
RAID 3에는 오류 검출 코드인 패리티 비트를 하나의 디스크에만 저장하기에 해당 디스크가 고장나면 큰 문제가 발생합니다.
그러나 5,6에서는 패리티 비트를 여러 디스크에 분산하여 저장함으로서 이러한 문제를 해결했습니다.
기타 질문
커널 모드와 사용자 모드의 차이에 대해 간단히 설명해주세요.
커널 모드는 운영체제가 CPU를 제어하고 있을 때에 해당합니다. 여기에서 운영체제는 코드가 실행되며, 모든 종류의 명령, 특히 하드웨어를 직접 제어하는 등의 특권 명령을 수행할 수 있습니다.
반면 사용자 모드는 사용자 프로그램이 CPU의 제어권을 가지고 제한적인 명령만 실행할 수 있는 모드입니다.
사용자 프로그램이 특권 명령을 실행 하기 위해서는 운영체제에게 이 명령을 대신해줄 것을 요청하는데, 이를 시스템 콜이라고 합니다.
즉 프로그램이 자신의 주소 공간 내에 있는 함수가 아닌 커널의 함수를 호출하는 것을 뜻합니다.
특권 명령 - 사용자 프로그램이 사용했을 때 큰 문제가 발생할 수 있는 명령으로, 보안 과 관련되어있으며 mode bit가 0일때 사용 가능
시스템 콜이란 무엇인가요?
시스템 콜(system call)은 사용자 모드에서 실행되는 프로그램이 운영체제의 서비스를 요청하기 위한 일종의 인터페이스입니다. 사용자 모드에서 실행되는 프로그램이 보안이 필요한 작업을 수행하거나 하드웨어와 같은 시스템 자원에 접근하고자 할 때 직접적으로 이를 수행할 수 없기 때문에, 운영체제가 이런 작업을 대신해주도록 요청하는데 이것이 바로 시스템 콜입니다.
예를 들어, 파일을 열거나 네트워크 통신을 하고자 하는 등의 작업이 시스템 콜을 통해 이루어지게 됩니다. 시스템 콜을 사용하면 운영체제는 프로그램에 필요한 서비스를 제공하면서도, 보안을 유지하고 시스템의 안정성을 보장할 수 있습니다.
이거 또한 인터럽트처럼 인터럽트 라인에 인터럽트를 세팅함으로서 이루어짐.
시스템 콜을 발생시킨 후 어떤 과정이 발생하나요?
사용자 프로그램이 시스템 콜을 호출하면 (예: 디스크로 파일을 읽어오는 경우), CPU의 제어권이 운영체제로 넘어갑니다. 이때 사용자 프로그램의 상태, 즉 프로세스의 컨텍스트(Context)는 프로세스 제어 블록(Process Control Block, PCB)에 저장됩니다.
다음으로 CPU는 커널 모드로 전환되고, 운영체제는 시스템 콜에 해당하는 서비스 루틴을 실행합니다. 예를 들어, 디스크에서 파일을 읽어오는 시스템 콜의 경우, 운영체제는 디스크 컨트롤러에게 해당 파일을 읽어오라는 명령을 내립니다
만약 시스템 콜이 블로킹 연산이라면, 해당 시스템 콜을 호출한 프로세스는 봉쇄 상태로 전환되며, CPU 제어권은 다른 프로세스에게 넘어갑니다. 시스템 콜이 완료되면, 원래의 프로세스는 준비 상태(ready state)가 되고, 스케줄러에 의해 다시 실행 상태(running state)로 전환될 수 있습니다
반면, 시스템 콜이 논-블로킹 연산이라면, 해당 시스템 콜을 호출한 프로세스는 제어권을 즉시 다시 얻게 되고, 다른 작업을 계속 수행할 수 있습니다.
블로킹 - 특정 작업이 완료될때까지 프로그램의 실행이 멈춤. 이 시간 동안 프로세스는 CPU를 사용하지 않고, 다른 CPu가 사용할 수 있도록 봉쇄상태
논블로킹 - 특정 작업(예: 입출력 요청)이 완료되지 않더라도 프로그램의 실행이 계속됩니다. 이 방식에서는 작업의 완료 여부와 관계 없이 즉시 제어가 프로그램으로 돌아갑니다
이 경우, 프로세스는 시스템 콜의 결과를 나중에 확인하게 될 수도 있습니다.
모드 비트가 무엇인지 설명해주세요.
모드 비트(mode bit)는 CPU의 상태를 나타내는 비트로서, 현재 CPU가 어떤 모드에서 실행되고 있는지를 표시합니다. 일반적으로 이 비트는 1 또는 0의 값을 가질 수 있습니다.
모드 비트가 0일 경우, CPU는 커널 모드(Kernel Mode)에서 실행되고 있는 것으로, 모든 종류의 명령어를 실행할 수 있는 상태를 나타냅니다. 이 모드에서는 입출력 관리, 메모리 관리, 파일 시스템 관리 등의 중요한 시스템 연산을 수행할 수 있습니다.
반면, 모드 비트가 1일 경우, CPU는 사용자 모드(User Mode)에서 실행되고 있는 것으로, 제한된 명령어만 실행할 수 있는 상태를 나타냅니다. 이 모드에서는 일반적인 프로그램 실행을 수행하며, 보안이 필요한 작업이 필요할 경우 시스템 콜을 통해 이를 커널 모드로 전환하여 수행하게 됩니다.
따라서 모드 비트는 운영체제가 사용자 프로그램과 시스템의 민감한 자원 간의 보안을 유지하면서도 필요한 작업을 수행할 수 있도록 하는 중요한 역할을 합니다.
사용 이유 - 사용자 프로그램이 CPU 제어권을 가지고 있을 때 운영체제가 이를 제어하지 못하므로
시분할 시스템(Time Sharing)이란 무엇이죠??
시분할 시스템이란 다중 사용자 지원을 위해 컴퓨터 응답 시간을 최소화하는 시스템입니다. 이때 응답 시간을 최소화 하기 위해 각 응용 프로그램이 CPU를 점유하는 시간을 잘게 쪼개어 실행 될 수 있게 해줍니다.
이를 통해 각 사용자는 독립적인 컴퓨팅 환경을 가진것 처럼 느낄 수 있습니다.
(만약 100시간 짜리 프로세스가 1,2시간 짜리 보다 먼저 등록되었다면??? 비효율적 -> 이를 해결하기 위해 등장)
유사 질문 1 - 멀티 태스킹이란 무엇인가??
단일 CPU 환경에서 여러 응용프로그램이 동시에 실행되는 것처럼 보이게 하는 시스템입니다.
이때 응답시간 ~~~ (위랑 똑같이 대답)
참고 - 멀티태스킹은 시분할 시스템과 목표는 다르지만, 결과적으로 구현방식은 거의 동일한 시스템이라고 이해
유사질문 2 - 멀티 프로그래밍이란 무엇인가??
멀티 프로그래밍이란 메모리에 여러 프로그램을 동시에 올리는 기능입니다. 이를 통해 CPU가 한 프로그램에서 다른 프로그램으로 빠르게 전환함으로써,CPU의 이용률을 극대화할 수 있습니다.
만약 예시를 들어보라 할 경우
예를들어 만약 프로그램이 입출력 작업을 수행한다면, 이는 CPU처리 속도에 비해 느리기 때문에 CPU는 유휴 상태에 빠지게 됩니다.
이런 상황에서 메모리에 다른 프로그램이 올려져 있다면, 입출력 작업 동안 CPU는 대기 하는 것이 아닌, 다른 프로그램을 실행함으로서 CPU를 효율적으로 사용할 수 있습니다.
유사질문 3 - 멀티 프로세싱은 무엇인가?
멀티 프로세싱은 여러 CPU에 하나의 프로세스를 여러 단위로 쪼개 병렬로 실행하게끔 해서 실행 속도를 극대화 시키는 시스템입니다.
OS의 커널과 쉘에 대해 설명해주세요.
커널이란 메모리에 상주하는 운영체제의 핵심 부분(하드웨어 제어 뿐 아니라, 프로세스 및 메모리 관리도 진행)을 말합니다.
쉘은 사용자와 커널 사이에 위치해서 사용자가 명령어를 통해 커널이 소통할 수 있도록 명령어 해석기 역할을 합니다.
(대표적인 쉘로 unix 계열에서 사용하는 sh,bash,csh)
외부 프로세스간 통신 방법에 대해 설명해주세요.(IPC는 내부 프로세스 간 통신)
소켓을 이용하여 서버와 클라이언트 사이에서 데이터를 전송할 수 있습니다(IP기반).
RPC는 로컬 컴퓨터에서 실행되는 함수를 원격 컴퓨터에서 호출할 수 있도록 하는 프로토콜로, RPC를 이용하여 서버와 클라이언트 사이에서 함수를 호출하고 결과를 전송할 수 있습니다.
REST API는 HTTP 프로토콜을 기반으로 동작하고, 이를 통해 서버와 클라이언트 사이에서 데이터를 전송할 수 있습니다.(최근 주로 사용)
OS가 메모리 관리를 해야하는 이유에 대해 설명해주시고, 메모리 관리를 위해 어떤 전략을 사용하는지 설명해주세요.
우선, 각각의 프로세스는 독립된 메모리 공간을 갖습니다. 따라서 각 프로세스는 다른 프로세스의 메모리 공간에 접근할 수 없습니다. 오로지 ‘운영체제’만이 운영체제 메모리 영역과 사용자 메모리 영역의 접근에 영향을 받지 않습니다. 따라서 OS 만이 메모리를 관리할 수 있기 때문에 적절한 관리가 필요합니다.
가상메모리를 이용한 Swapping, 페이징 및 세그멘테이션 전략, 고정 길이 할당 / 가변 길이 할당, 압축 등의 방식으로 OS가 메모리 관리를 수행할 수 있습니다.
캐시(cache) 메모리를 왜 사용하는지, CPU의 적중률을 높이기 위해 어떤 원리를 사용하는지에 대해 설명해주세요.
CPU와 메모리 사이의 속도 차이를 완화하기 위해 사용합니다.
메모리의 데이터를 미리 가져와 저장해두는 임시 장소로, 캐시의 크기는 메인 메모리보다 작기 때문에 앞으로 사용될 것으로 예상하는 데이터를 미리 저장하는 것이 중요한 포인트입니다.
따라서 이 캐시에 있는 데이터를 사용하는 것을 ‘적중’이라고 하고, 이러한 적중률을 높이기 위해서 참조 지역성의 원리를 사용합니다.
- 최근에 참조된 주소의 내용은 곧 다음에 다시 참조되는 특성 (ex. 반복문, 시간지역성)
- 참조된 주소와 인접한 주소의 내용이 다시 참조되는 특성 (ex. 배열, 공간지역성)
힙영역을 크게 잡으면 안되는 이유
GC의 수행 시간이 너무 오래 걸리게 된다.
프로세스 종류
자식 프로세스 - fork로 자식 프로세스를 만든 상태, 부모의 데이터, 힙, 스택, PCB 복사
데몬 프로세스 - 백그라운드에서 동작하면서 특정한 서비스를 제공하는 프로세스
고아 프로세스 - 부모 프로세스가 먼저 종료되어 고립된 자식 프로세스
좀비 프로세스 - 자식 프로세스가 종료되었음에도 불구하고 부모 프로세스로부터 작업 종료에 대한 승인을 받지 못한 프로세스
동시성과 병렬성이 어떻게 다른지 설명해주세요.
동시성은 멀티 프로그래밍 (Multi-Programming)에서 나온 개념으로, 주기억장치에 여러 프로세스를 적재해서 Context Switching을 통해 동시에 실행되는 것 처럼 보이게 하는 것을 의미합니다. 실제로는 동시에 실행되는 것이 아니라, 번갈아 실행하는 것입니다. 싱글 코어에서 멀티스레드를 동작시키기 위한 방식입니다.
병렬성은 멀티 프로세싱 (Multi-Processing)에서 나온 개념으로, 실제로 동시에 여러 프로세스를 병렬적으로 실행하는 방식입니다. 병렬적으로 실행하기 위해서는 CPU가 멀티코어여야 합니다.
동기 비동기 차이
“동기는 요청과 그 결과가 순차적으로 이루어지는 방식으로, 요청을 한 후 해당 작업이 완료될 때까지 기다린 후 다음 작업을 수행합니다. 반면, 비동기는 요청을 하고 바로 다음 작업을 진행하는 방식으로, 이전 요청의 작업 완료 여부와 상관없이 뒤따르는 작업을 계속해서 수행합니다. 이로 인해 비동기 방식은 효율적으로 시스템 자원을 활용할 수 있지만, 동기 방식보다 복잡한 프로그래밍이 필요할 수 있습니다.”
식사하는 철학자 문제
식사하는 철학자 문제는 동시성 제어와 교착 상태(deadlock)를 설명하는데 널리 사용되는문제입니다.
5명의 철학자가 원탁에 앉아 각자 생각하다가 배가 고프면 젓가락으로 음식을 먹습니다. 각 철학자 사이에는 젓가락이 하나씩 놓여 있어, 철학자는 자신의 양 옆에 있는 두 개의 젓가락을 사용해야만 음식을 먹을 수 있습니다.
이 문제는 다음과 같은 복잡성을 가지고 있습니다
동시에 여러 철학자가 음식을 먹기 위해 젓가락을 집으려 할 때, 서로가 필요로 하는 젓가락을 점유하고 있어 교착 상태에 빠질 수 있습니다.
모든 철학자가 동시에 왼쪽 젓가락을 집으면, 오른쪽 젓가락을 집을 수 없기 때문에 교착 상태가 발생합니다.
또한, 하나의 철학자만 계속 음식을 먹고 다른 철학자들은 기회를 얻지 못하는 ‘기아’ 상태도 발생할 수 있습니다.
해결책(참고만 하자)
상호 배제: 철학자가 젓가락을 집을 때, 다른 철학자가 해당 젓가락을 집을 수 없도록 상호 배제를 활용
젓가락 요청 순서 지정: 철학자들이 젓가락을 요청하는 순서를 정해 놓고, 그 순서대로 젓가락을 집게 하는 방법입니다. 예를 들어, 홀수 번호의 철학자는 먼저 왼쪽 젓가락을, 짝수 번호의 철학자는 먼저 오른쪽 젓가락을 집게 합니다.
대기 시간 제한: 철학자가 젓가락을 얻기 위해 일정 시간 동안만 기다리게 하여, 그 시간이 초과하면 다른 행동을 하도록 유도하는 방법입니다.