https://github.com/JaeYeopHan/Interview_Question_for_Beginner 위 링크에 있는 문제에 대한 답안을 정리해보았다.
운영체제
프로세스와 스레드의 차이
- 프로그램이란?
- 실행가능한 명령어의 집합
- 프로세스란?
- 컴퓨터에서 연속적으로 실행되고 있는 프로그램
- 정적인 프로그램과 달리 실제 실행 중이기 때문에 동적
- 운영체제로부터 시스템 자원을 할당받는 작업의 단위
- 유저가 사용하는 메모리 공간 상의 프로세스 정보는 다음과 같이 나뉜다
- Code(text): 프로그램의 실제 코드를 저장
- Data: 프로세스가 실행될 때 정의된 전역 변수,Static 변수들을 저장
- Heap: 프로세스 런타임 중 동적으로 할당되는 변수들을 저장(함수 내에서 할당되는 변수 등)
- Stack: 함수에서 다른 함수를 실행하는 등의 서브루틴들의 정보를 저장(재귀와 스택이 관련 있는 이유)
- 운영체제는 각각의 프로세스를 독립적으로 관리하기 때문에 서로 다른 프로세스가 겹칠 일이 없다
- 때문에 각 프로세스가 다른 프로세스의 정보를 변경하는 것을 극도로 주의하며 필요한 경우 최소한의 인터페이스를 제공해 소통할 수 있게 한다. 이런 프로세스간 소통을 Inter Process Communication(IPC)라고 한다
- 스레드
- 프로세스 내에서 실행되는 흐름
- 하나의 프로세스는 하나의 스레드로 시작되며 이를 메인 스레드라 한다
- 현대적인 운영체제는 하나의 프로세스 내에 여러 스레드가 존재할 수 있는 멀티스레딩을 지원한다. 왜일까?
- 순차적인 방식은 한 작업이 오래 걸리면 전체 프로그램이 지연되는 병목현상이 생길 수 있음. 멀티 스레드의 경우 이런 문제점을 방지
- 스레드의 장점
- 프로세스 간 통신에 비해 스레드 간 통신이 훨씬 간단하다
- 시스템의 자원 소모가 줄어든다
- 기존 프로세스 자원을 다른 스레드와 공유
- 전체 응답 시간이 줄어든다
- 스레드의 단점 - 여러 스레드를 이용하는 경우 설계에 더 신경을 써야 한다 - 디버깅이 어렵다
- 프로세스와 스레드의 차이
- 프로세스는 운영체제로부터 독립된 시간, 공간 자원을 받아 할당되고 스레드는 한 프로세스 내에서 많은 자원을 공유하며 병렬적으로 실행된다
- 프로세스는 독립적. 스레드는 독립적이지 않음. 여러 스레드가 같은 프로세스 자원을 공유하기 때문.
- 프로세스간 통신은 스레드간 통신보다 어려움. 프로세스는 시스템이 제공하는 IPC 메커니즘을 통해서만 통신할 수 있고 시스템에 의해 관리되기 때문에 상재적으로 안전. 반면 스레드는 통신이 용이하지만 안전성이 떨어진다.
- Context Switch에 있어서도 스레드가 일반적으로 더 빠르고 자원소모가 적다. 프로세스는 Switch 될 때 Context를 PCB에 저장하는 등 오버헤드가 발생하는데 스레드는 그런 부하가 적다.
- 참조
- https://shoark7.github.io/programming/knowledge/difference-between-process-and-thread
스케줄러의 종류
- 스케줄링: 시스템이 실행하고자 할 때 프로세서를 프로그램들에게 할당하는 과정
- 프로세스는 자신의 임무를 수행하고 사라질 때까지 많은 큐를 돌아다님
- 이때 프로그램들은 제한된 프로세서(CPU)를 서로 사용하려고 함
- OS는 이러한 프로세스 중 하나를 택하는데, 스케줄러가 이 역할을 담당
- 프로세스를 스케줄링하는 큐에는 세 가지 종류가 존재
- Job Queue: 현재 시스템 내에 있는 모든 프로세스의 집합
- Ready Queue: 현재 메모리 내에 있으면서 CPU를 잡아서 실행되기를 기다리는 프로세스의 집합
- Device Queue: Device I/O 작업을 대기하고 있는 프로세스의 집합 각각의 Queue에 프로세스들을 넣고 빼주는 스케줄러에도 세 가지 종류가 존재
- 장기 스케줄러 (Long-term scheduler or job scheduler)
- 메모리는 한정되어 있는데 많은 프로세스들이 한꺼번에 메모리에 올라올 경우, 대용량 메모리에 임시로 저장됨. 이 pool에 저장되어 있는 프로세스 중 어떤 프로세스에 메모리를 할당하여 ready queue로 보낼지 결정
- 메모리와 디스크 사이의 스케줄링을 담당
- 프로세스에 memory를 할당
- degree of Multiprogramming 제어. 메모리에 몇 개의 프로그램이 올라갈지를 제어
- 프로세스의 상태: new -> ready
- 단기 스케줄러 (Short-term scheduler or CPU scheduler)
- CPU와 메모리 사이의 스케줄링을 담당
- Ready Queue에 존재하는 프로세스 중 어떤 프로세스를 running 시킬지 결정
- 프로세스에 CPU를 할당
- 프로세스의 상태: ready -> running - waiting -> ready
- 중기 스케줄러 (Medium-term sheculer or Swapper)
- 여유 공간 마련을 위해 프로세스를 통째로 메모리에서 디스크로 쫓아냄 (Swapping)
- 프로세스에게서 memory를 deallocate
- degree of Multiprogramming 제어
- 현 시스템에서 메모리에 너무 많은 프로그램이 동시에 올라가는 것을 조절하는 스케줄러
- 프로세스의 상태: ready -> suspended
- 참조
- https://github.com/JaeYeopHan/Interview_Question_for_Beginner/tree/master/OS
- https://shoark7.github.io/programming/knowledge/difference-between-process-and-thread
CPU 스케줄러
- 스케줄링 대상은 Ready Queue에 있는 프로세스들
- FCFS (First Come First Served)
- 먼저 온 순서대로 처리
- 비선점형 (Non-preemptive) 스케줄링
- 일단 CPU를 잡으면 CPU burst가 완료될 때까지 CPU를 반환하지 않는다. 할당되었던 CPU가 반환될 때만 스케줄링이 이루어진다
- CPU를 사용중인 프로세스가 자율적으로 반납
- Time-slice가 없음
- 문제점 - convoy effect: 소요시간이 긴 프로세스가 먼저 도달하여 효율성을 낮추는 현상이 발생한다
- SJF (Shortest - Job - First)
- CPU burst time이 짧은 프로세스에게 선 할당
- 비선점형(Non-Preemptive) 스케줄링
- 문제점
- starvation: 사용시간이 긴 프로세스는 거의 영원히 CPU를 할당받을 수 없음
- SRT(Shortest Remaining time First)
- 최단 잔여시간을 우선으로 하는 스케줄링
- 새로운 프로세스가 도착할 때마다 새로운 스케줄링이 이루어짐
- 선점형(Preemptive) 스케줄링
- 현재 수행 중인 프로세스의 남은 burst time 보다 더 짧은 CPU birst time을 갖는 새로운 프로세스가 도착하면 CPU를 뺏긴다
- 문제점 - 새로운 프로세스가 도달할 때마다 스케줄링을 다시하기 때문에 CPU birst time을 측정할 수가 없다
- Priority Scheduling
- 우선순위가 가장 높은 프로세스에 CPU를 할당. 우선순위는 정수로 표현, 작은 숫자가 우선순위가 높음
- 선점형 스케줄링 방식
- 더 높은 우선순위의 프로세스가 도착하면 실행중인 프로세스를 멈추고 CPU를 선점
- 비선점형 스케줄링 방식
- 더 높은 우선순위의 프로세스가 도착하면 Ready Queue의 Head에 넣는다
- 문제점 - starvation - Indefinite blocking: 실행 준비는 되어있으나 CPU를 사용 못하는 프로세스를 CPU가 무기한 대기하는 상태
- 해결책 - aging: 우선순위가 낮은 프로세스라도 오래 기다리면 우선순위를 높여줌
- Round Robin
- 현대적인 CPU 스케줄링
- 각 프로세스는 동일한 크기의 할당 시간을 갖게 됨
- 할당 시간이 지나면 프로세스는 선점당하고 ready queue의 뒤에 가서 다시 줄을 선다
- CPU 사용시간이 랜덤한 프로세스가 섞여있을 경우 효율적
- 장점
- Response time이 빨라진다
- 프로세스가 기다리는 시간이 CPU를 사용할 만큼 증가한다. 공정한 스케줄링.
- 참조
- https://github.com/JaeYeopHan/Interview_Question_for_Beginner/tree/master/OS
- https://hyunah030.tistory.com/4
동기와 비동기의 차이
- 동기
- 요청과 그 결과가 동시에 일어난다
- 값이 반환되기 전까지는 blocking 되어 있음
- 장점: 설계가 간단하고 직관적
- 단점: 결과를 볼 때까지 아무것도 못하고 대기해야함
- 비동기
- 요청과 결과가 동시에 일어나지 않음
- 장점: 결과가 주어지는데 시간이 걸리더라도 그 시간 동안 다른 작업이 가능해 자원의 효율적인 사용이 가능
- 단점: 설계가 복잡함
멀티 스레드
- 장점
- 메모리 공간과 시스템 자원 소모가 줄어든다
- 스레드 간 통신이 필요한 경우에도 Heap 영역을 이용하여 데이터를 주고 받을 수 있다. 프로세스 간 통신 방법에 비해 훨씬 간단함.
- 실행의 흐름을 명확히 분리할 수 있다
- 대기 시간, 응답시간을 최소화 할 수 있다
- 단점
- 구현하기 어려움
- 테스트, 디버깅하기 어려움
- 다른 스레드가 데이터와 힙 영역을 공유하기 때문에 다른 스레드에서 사용중인 변수나 자료구조에 접근하여 문제를 일으킬 수 있음
- 때문에 동기화 작업 필요. 이로 인해 병목현상이 발생하여 성능이 저하될 수 있음
프로세스 동기화
- 프로세스가 공유 자원을 사용하는 상황에서, 경쟁 조건이 발생하면 공유 자원을 신뢰할 수 없게 만들 수 있음. 이를 방지하기 위해 공유 자원을 사용할 때 특별한 규칙을 만드는 것이 프로세스 동기화
- 경쟁 조건 (Race Condition)
- 여러 프로세스(또는 스레드)가 공유 자원에 동시에 접근할 때, 공유 자원에 대한 접근 순서에 따라 실행 결과가 달라질 수 있는 상황
- Critical Section (임계영역)
- 여러 프로세스(또는 스레드)가 자원을 공유하는 상황에서, 하나의 프로세스(스레드)만 접근할 수 있도록 제한해둔 코드 영역
- Critical Section 문제의 해결 조건
- 상호 배제(Mutual Exclusion): 어떤 프로세스(또는 스레드)가 임계 구역에서 작업 중일 때, 다른 프로세스는 임계 구역으로 접근할 수 없다
- 진행 (Process): 임계 구역에서 작업 중인 프로세스가 없다면, 임계 구역으로 진입하려는 프로세스 중 하나를 선택하여 진입할 수 있게 해야 한다
- 유한 대기 (Bounded Wating): 다른 프로세스의 starvation을 방지하기 위해, 임계 구역에 한 번 접근했던 프로세스는 다시 임계구역에 들어갈 때 제한을 두어야 한다
- 해결책
- 하드웨어 동기화 방법
- lock을 이용한 해결책. 특정 프로세스가 공유 자원에 접근 중일 때는 다른 프로세스는 접근 하지 못하도록 Lock을 건다.
- 싱글 프로세서 환경에서는 공유 데이터가 변경되는 동안 인터럽트를 막으면 임계 구역 문제를 해결할 수 있다. 비선점형 커널에서도 이 방법을 사용한다
- 고전적인 소프트웨어 해결책: 피터슨 알고리즘, 데커 알고리즘 - CPU가 여러 개일 때는 동작 안함
- 하드웨어 동기화 방법
- 세마포어 (Semaphore)
- Critical Section 문제를 해결하기 위한 동기화 도구
- 종류
- 카운팅 세마포 (counting semaphore)
- 세마포는 공유자원의 개수를 나타내는 변수임
- ex) 다섯 대의 프린터가 있을 때 세마포는 5. 사용할 프린터가 없어지면 0.
- 사용가능한 자원의 개수로 초기화됨
- 이진 세마포 (binary semaphore) - MUTEX 라고도 함 - shared data의 개수 - ex) 두 개의 기차가 동시에 이용하는 기찻길이 있을 때, 어떤 기차가 지나가고 있으면 0, 비어있으면 1
- 카운팅 세마포 (counting semaphore)
- 단점 - Busy Waiting(바쁜 대기) - lock의 해제를 기다리는 동안 빈 반복문을 반복해서 돌기 때문에 context switching이 발생
- 해결방법 - block()을 통해서 프로세스를 대기 상태로 전환하고 CPU 스케줄링을 실행
- Deadlock (교착상태) - 세마포가 Ready Queue를 가지고 있고, 둘 이상의 프로세스가 Critical Section 진입을 무한정 기다리고 있고, Critical Section에서 실행되는 프로세스는 진입 대기 중인 프로세스가 실행되야만 빠져나올 수 있는 상황
- 참조
- https://github.com/JaeYeopHan/Interview_Question_for_Beginner/tree/master/OS
- https://jhnyang.tistory.com/101
- https://jungwoon.github.io/os/2019/07/31/Process-Synchronization/
메모리 관리 전략
- 메모리는 CPU가 직접 접근하는 유일한 저장장치. 메모리 시스템(하드웨어)은 주소(메모리 위치)를 관리하며 할당과 접근을 제어한다.
- 목적
- 제한된 물리 메모리의 효율적인 사용 (할당)
- 효율적인 메모리 참조 (논리-물리 주소 할당)
메모리 전략
- Swapping
- CPU 할당 시간이 끝난 프로세스의 메모리를 보조 기억장치로 내보내고 다른 프로세스의 메모리를 불러들임
- Swap in: 주 기억장치(RAM)으로 불러옴
- Swap out: 메모리 공간이 부족하면 보조 기억장치로 내보냄
- Fragmentation (단편화)
- 프로세스들이 메모리에 적재되고 제거되는 일이 반복되다 보면 프로세스들이 차지하는 메모리 틈 사이에 사용 하지 못할 만큼의 작은 자유 공간들이 늘어남. 이것이 단편화
- 종류
- 외부 단편화: 메모리 공간 중 사용하지 못하게 되는 일부분. 물리 메모리에서 사이사이 남는 공간들을 모두 합치면 충분한 공간이 되는 부분들이 분산되어 있을 때 발생
- 내부 단편화: 할당된 기억 공간이 요청된 기억 공간보다 더 커 기억 공간이 남는 현상
- Paging (페이징)
- 단편화의 문제를 해결하기 위해 프로그램 전체를 연속된 공간에 적재하지 않고 일정 크기의 단위로 나누어서 분산 적재하는 방법
- 물리 메모리는 Frame이라는 고정 크기로 분리되어 있고, 논리 메모리는 페이지라 불리는 고정 크기의 블록으로 분리됨
- 논리 메모리는 물리 메모리에 저장될 때, 연속되어 저장될 필요가 없고 물리 메모리의 남는 프레임에 적절히 배치됨으로써 외부 단편화를 해결
- Segmentation
- 페이징처럼 논리 메모리와 물리 메모리를 같은 크기의 블록이 아닌, 서로 다른 크기의 논리적 단위인 세크먼트로 분할.
- 단점: 서로 다른 크기의 세그먼트들이 메모리에 적재되고 제거되는 일이 반복되다 보면, 자유 공간들이 많은 수의 조각으로 나뉘어져 못 쓸 수도 있다 (외부 단편화)
- 참조
- http://blog.naver.com/PostView.nhn?blogId=yeop9657&logNo=220728971005&parentCategoryNo=&categoryNo=145&viewDate=&isShowPopularPosts=true&from=search
- https://jungwoon.github.io/os/2019/07/31/Virtual-Memory/
- https://github.com/JaeYeopHan/Interview_Question_for_Beginner/tree/master/OS