운영체제 공룡책 강의
카테고리: Operating System
Chapter 01 서론
01-1 운영체제가 할 일
- Chapter 1,2 는 딱히 중요한 내용이 없으니 쭉 훑어보면 된다
- Chapter 3~10 이 중요한데 그 중에서도 Chapter 3~8 이 중요하다
- 운영체제는 여러 사용자를 위해 다양한 응용 프로그램 간의 하드웨어 사용을 제어하고 조정한다
- 운영체제의 일반적인 정의는 컴퓨터에서 항상 실행되는 프로그램(일반적으로 커널이라고 함)이다
01-2 컴퓨터 시스템의 구성
- 현대의 범용 컴퓨터 시스템은 하나 이상의 CPU와 구성요소와 공유 메모리 사이의 액세스를 제공하는 공통 버스를 통해 연결된 여러 장치 컨트롤러로 구성된다
- 컨트롤러는 장치 드라이버에게 작업을 완료했다는 사실을 어떻게 알리는가? 이는 인터럽트를 통해 이루어진다
- 하드웨어는 어느 순간이든 시스템 버스를 통해 CPU에 신호를 보내 인터럽트를 발생시킬 수 있다
- 컴퓨터 전원을 켤 때 가정 먼저 실행되는 프로그램은 부트스트랩 프로그램이며 운영체제를 적재한다
- 폰 노이만 구조 시스템에서 실행되는 명령-실행 사이클 순서를 알아두자 ( CPU가 메모리에 저장된 명령어를 받아와 계산할 때 메모리로부터 명령어를 가져오는 fetch, 명령어의 의미를 해석하는 decode, 명령어를 실행하는 execute, 결과를 저장하는 store의 순서로 처리된다 )
- Instruction register는 명령어를 호출해서 해독하기 위해 명령어를 잠시 보관해 두는 특수 목적 레지스터이다 현재 실행되거나 디코딩되고 있는 명령을 보관하고 있는 CPU의 제어 장치의 일부이다
- 다양한 저장장치 시스템은 저장 용량 및 엑세스 시간에 따라 계층 구조로 구성될 수 있다
01-3 컴퓨터 시스템 구조
- 코어는 명령을 실행하고 로컬로 데이터를 저장하기 위한 레지스터를 포함하는 구성요소이다
- 단일 처리 코어를 가진 범용 CPU가 하나만 있는 경우 시스템은 단일 프로세서 시스템이다 그러나 현대 컴퓨터 시스템은 단일 프로세서 시스템이 거의 없다
- 멀티프로세서 시스템은 단일 코어 CPU가 있는 두개 이상의 프로세서가 있다
- 가장 일반적인 멀티프로세서 시스템은 각 피어 CPU 프로세서가 운영체제 기능 및 사용자 프로세스를 포함한 모든 작업을 수행하는 SMP를 사용한다
- CPU는 명령을 실행하는 하드웨어 이다
- 프로세서는 하나 이상의 CPU를 포함하는 물리적 칩이다
- 코어는 CPU의 기본 계산 단위이다
- 멀티코어는 동일한 CPU에 여러 컴퓨팅 코어를 포함함을 뜻한다
- 멀티프로세서는 여러 프로세서를 포함함을 뜻한다
01-4 운영체제의 작동
- 멀티프로그래밍 시스템은 주기억장치에 적재된 여러 개의 프로그램들을 CPU가 항상 수행하도록 하여 CPU 이용률을 증진시킨다
- 멀티프로그래밍 시스템에서 실행 중인 프로그램을 프로세스라고 한다
- 멀티태스킹은 멀티프로그래밍의 논리적 확장이다
- 멀티태스킹 시스템에서 CPU는 여러 프로세스를 전환하며 프로세스를 실행하지만 전환이 자주 발생하여 사용자에게 빠른 응답 시간을 제공하게 된다
- 응용 프로그램이 운영체제에게 서비스를 요청하면(시스템 콜을 통함) 이 요청을 수행하기 위해서는 사용자 모드에서 커널 모드로 전환해야 한다
01-7 가상화
01-10 계산 환경
- 모바일 컴퓨팅은 휴대용 스마트폰과 태블릿 컴퓨터의 컴퓨팅 환경을 말한다 이들 장치들은 이동 가능하고 가볍다는 구별되는 물리적 특징을 공유한다
- 현대 네트워크 구조는 서버 시스템이 클라이언트 시스템이 생성한 요청을 만족시키는 배치를 특징으로 한다
- 피어 간 시스템 모델에서는 클라이언트와 서버가 서로 구별되지 않는다 대신 시스템상의 모든 노드가 피어로 간주되고 각 피어는 서비스를 요청하느냐 제공하느냐에 따라 클라이언트 및 서버로 동작한다
- 클라우드 컴퓨팅은 계산, 저장장치는 물론 응용조차도 네트워크를 통한 서비스로 제공하는 계산 유형이다 어떤 면에서 클라우드 컴퓨팅은 가상화를 그 기능의 기반으로 사용하기 때문에 가상화의 논리적 확장이다
Chapter 02 운영체제 구조
02-1 운영체제 서비스
- 프로그램 수행 : 시스템은 프로그램을 메모리에 적재해 실행 할 수 있어야 한다 프로그램은 정상적이든, 혹은 비정상적이든 실행을 끝낼 수 있어야 한다
02-2 사용자와 운영체제 인터페이스
- CLI 방식은 명령어 라인 인터페이스 또는 명령 인터프리터를 제공하는 것이다 이명령어 라인 인터페이스는 사용자가 운영체제가 수행할 명령어를 직접 입력할 수 있도록 한다
- 운영체제와 접촉하는 두 번째 방식은 사용자 친화적인 그래픽 기반 사용자 인터페이스 또는 GUI를 통하는 방식이다
02-3 시스템 콜
- 시스템 콜은 운영체제에 의해 사용 가능하게 된 서비스에 대한 인터페이스를 제공한다
- printf() 문을 호출하는 C 프로그램을 예로들면 C 라이브러리는 이 함수 호출을 가로채고 운영체제의 필요한 시스템 콜을 부른다 이 예에서는 write() 시스템 콜이 불린다
Chapter 03 프로세스
03-1 프로세스 개념
- 프로세스란 실행 중인 프로그램을 말한다, 프로세스는 현대의 컴퓨팅 시스템에서 작업의 단위이다
- 프로세스 메모리 배치에서 텍스트 섹션에는 실행 코드가 적재되고 데이터 섹션에는 전역변수가 적재되며 힙 섹션에는 프로그램 실행 중에 동적으로 할당된 메모리가 적재되고 스택 섹션에는 함수를 호출할 때 임시 데이터가 적재된다( 함수 매개변수, 복귀 주소, 지역 변수 )
- 각 프로세스는 운영체제에서 프로세스 제어 블록(PCB)에 의해 표현된다
- PCB는 특정 프로세스와 연관된 여러 정보를 수록한다
- PCB는 프로세스를 시작하거나 다시 시작시키는데 필요한 모든 데이터를 위한 저장소의 역할을 한다
03-2 프로세스 스케줄링
- 다중 프로그래밍의 목적은 CPU 이용을 최대화하기 위하여 항상 어떤 프로세스가 실행 되도록 하는 데 있다
- 위의 목적을 달성하기 위해 프로세스 스케줄러는 코어에서 실행 가능한 여러 프로세스 중에서 하나의 프로세스를 선택한다
- 프로세스가 시스템에 들어가면 준비 큐에 들어가서 준비 상태가 되어 CPU 코어에서 실행되기를 기다린다 이 큐는 일반적으로 연결 리스트로 저장된다
- I/O 완료와 같은 특정 이벤트가 발생하기를 기다리는 프로세스는 대기 큐에 삽입된다
- 프로세스 스케쥴링을 나타내는 큐잉 다이어그램 ( P. 125 )
- CPU 코어를 다른 프로세스로 교환하려면 이전의 프로세스의 상태를 보관하고 새로운 프로세스의 보관된 상태를 복구하는 작업이 필요하다 이 작업을 문맥교환 이라고 하고 그림 3.6에 묘사된다 ( P. 127 )
03-3 프로세스에 대한 연산
- 실행되는 동안 프로세스는 여러 개의 새로운 프로세스들을 생성할 수 있다 앞에서 언급한 것과 같이 생성하는 프로세스를 부모 프로세스라고 부르고, 새로운 프로세스는 자식 프로세스라고 부른다
- Unix, Linux 및 Windows와 같은 대부분의 현대 운영체제들은 유일한 프로세스 식별자(pid)를 사용하여 프로세스를 구분하는데 이 식별자는 보통 정수이다
- 프로세스가 새로운 프로세스를 생성할 때, 두 프로세스를 실행시키는 데 두가지 가능한 방법이 존재한다 첫번째는 부모는 자식과 병행하게 실행을 계속한다 이며 두번째는 부모는 일부 또는 모든 자식이 실행을 종료할 때까지 기다린다 이다
- 새로운 프로세스들의 주소 공간 측면에서 볼 때 다음과 같은 두 가지 가능성이 있다 첫번째는 자식 프로세스는 부모 프로세스의 복사본이다 이며 두번째는 자식 프로세스가 자신에게 적재될 새로운 프로그램을 가지고 있다 이다
- fork()가 부모 프로세스로부터 주소 공간을 상속받는 자식 프로세스를 생성하는 반면에 CreateProcess()는 자식 프로세스가 생성될 때 주소 공간에 명시된 프로그램을 적재한다
- 종료되었지만 부모 프로세스가 아직 wait() 호출을 하지 않은 프로세스를 좀비 프로세스라고 한다
- 부모 프로세스가 wait()를 호출하는 대신 종료한다면 이 상황에 부닥친 자식 프로세스는 고아 프로세스가 된다
03-4 프로세스의 생성
- 프로세스 간 통신(IPC)는 기본적으로 공유 메모리와 메시지 전달의 두 가지 모델이 있다
- 메시지 전달 시스템은 통상 시스템 콜을 사용하여 구현되므로 커널 간섭 등의 부가적인 시간 소비 작업이 필요하기 때문에 공유 메모리 모델이 메시지 전달보다 더 빠르다
03-5 공유 메모리 시스템에서의 프로세스 간 통신
- 공유 메모리를 사용하는 프로세스 간 통신에서는 통신하는 프로세스들이 공유 메모리 영역을 구축해야 한다
- 일반적으로 운영체제는 한 프로세스가 다른 프로세스의 메모리에 접근하는 것을 금지한다는 것을 기억하자
- 생산자 프로세스는 정보를 생산하고 소비자 프로세스는 정보를 소비한다
- 생산자-소비자 문제의 하나의 해결책은 공유 메모리를 사용하는 것이다
03-6 메시지 전달 시스템에서의 프로세스 간 통신
- 공유 메모리에 접근하고 조작하는 코드가 응용 프로그래머에 의해 명시적으로 작성되어야 했다 동일한 효과를 얻는 또 다른 방법으로 운영체제가 메시지 전달 설비를 통하여 서로 협력하는 프로세스 간의 통신 수단을 제공해 주는 방법이 있다
- 직접 통신하에서, 통신을 원하는 각 프로세스는 통신의 수신자 또는 송신자의 이름을 명시해야 한다, 연결은 정확히 두 프로세스 사이에만 연관된다
- 간접 통신에서 메시지들은 메일박스 또는 포트로 송신되고, 그것으로부터 수신된다, 연결은 두 개 이상의 프로세스들과 연관될 수 있다
- 메일박스는 한 프로세스 또는 운영체제에 의해 소유될 수 있다
- 메일박스가 한 프로세스에 의해 소유된다면(즉, 메일박스가 프로세스의 주소 공간의 일부이다), 우리는 소유자(이 메일박스로부터 메시지를 수신만 가능한 프로세스)와 메일박스의 사용자(메일박스에 메시지를 송신만 할 수 있는 프로세스)를 구분할 수 있다
- 메시지 전달은 봉쇄형 이거나 비봉쇄형 방식으로 전달된다, 이 두 방식은 각각 동기식, 비동기식 이라고도 알려져 있다 ( 봉쇄형 보내기, 비봉쇄형 보내기, 봉쇄형 받기, 비봉쇄형 받기 )
03-7 IPC 시스템의 사례
- POSIX 공유 메모리는 메모리-사상 파일을 사용하여 구현된다
- shm_open() 시스템 콜을 사용하여 공유 메모리 객체를 생성해야 한다
- 생산자는 공유 메모리 객체를 구축하고 공유 메모리에 데이터를 쓰고, 소비자는 공유 메모리에서 데이터를 읽는다
- 소비자는 shm_unlink()함수를 호출하여 접근이 끝난 공유 메모리를 제거한다
- 파이프를 구현하기 위해서 고려해야 하는 문제는 책 참조 ( P. 155 )
- 일반 파이프(Ordinary Pipes)는 두 프로세스 간의 통신을 허용한다
- 일반 파이프(Ordinary Pipes)는 한쪽으로만 데이터를 전송할 수 있으며 오직 단방향 통신만을 가능하게 한다
- 통상 부모프로세스가 파이프를 생성하고 fork()로 생성한 자식 프로세스와 통신하기 위해 사용한다
03-8 클라이언트 서버 환경에서 통신
- 이 절에서는 클라이언트 서버에서 사용할 수 있는 두가지 다른 통신 전략에 대해서 설명한다 이 두가지는 소켓(sockets), 원격 프로시저 호출(RPCs)이다
- 소켓은 통신의 극점을 뜻한다, 각 소켓은 IP 주소와 포트 번호 두가지를 접합해서 구별한다
- 원격 프로시저 호출(RPC)는 프로시저 호출 기법을 추상화하는 방법으로 설계되었다
- RPC는 클라이언트가 원격 호스트의 프로시저를 호출하는 것을 마치 자기의 프로시저를 호출하는 것처럼 해준다
- RPC 시스템은 클라이언트 쪽에 스텁을 제공하여 통신을 하는데 필요한 자세한 사항들을 숨겨준다
- 스텁은 원격 서버의 포트를 찾고 매개변수를 정돈(marshall)한다
Chapter 04 스레드와 병행성
04-1 개요
- 스레드는 CPU 이용의 기본 단위이다
- 스레드는 스레드 ID, 프로그램 카운터(PC), 레지스터 집합, 그리고 스택으로 구성된다
- 다중 스레드 프로그래밍의 이점 1 : 응답성, 사용자에 대한 응답성을 증가시킨다
- 다중 스레드 프로그래밍의 이점 2 : 자원 공유, 코드와 데이터 공유의 이점은 한 응용 프로그램이 같은 주소 공간 내에 여러 개의 다른 작업을 하는 스레드를 가질 수 있다는 점이다
- 다중 스레드 프로그래밍의 이점 3 : 경제성, 스레드는 자신이 속한 프로세스의 자원들을 공유하기 때문에, 스레드를 생성하고 문맥 교환하는 것이 더욱더 경제적이다
- 다중 스레드 프로그래밍의 이점 4 : 규모 적응성, 다중 스레드의 이점은 다중 처리기 구조에서 더욱 증가 할 수 있다
04-2 다중 코어 프로그래밍
- Amdahl의 법칙이 시사하는 흥미 있는 사실 중 하나는 처리코어가 무한대에 가까워지면 속도는 1/S(S는 반드시 순차적으로 실행되어야만 하는 구성요소)에 수렴한다는 것이다
- Amdahl의 법칙에 따라 순차 실행 부분은 코어를 추가하여 얻을 수 있는 성능 향상에 불균형적인 영향을 미친다
- 다중 코어 시스템 프로그래밍 과제 1, 태스크 인식, 프로그램을 분석하여 독립된 병행 가능 태스크로 나눌 수 있는 영역을 찾는 작업이 필요하다
- 다중 코어 시스템 프로그래밍 과제 2, 균형, 전체 작업에 균등한 기여도를 가지도록 태스크를 나누는 것도 매우 중요하다
- 다중 코어 시스템 프로그래밍 과제 3, 데이터 분리, 태스크가 접근하고 조작하는 데이터 또한 개별 코어에서 사용할 수 있도록 나누어져야 한다
- 다중 코어 시스템 프로그래밍 과제 4, 데이터 종속성, 테스크가 접근하는 데이터는 둘 이상의 태스크 사이에 종속성이 없는지 검토되어야 한다
- 다중 코어 시스템 프로그래밍 과제 5, 시험 및 디버깅, 프로그램이 다중 코어에서 병렬로 실행될 때, 다양한 실행 경로가 존재할 수 있다
04-3 다중 스레드 모델
- 사용자 스레드는 커널 위에서 지원되며 커널의 지원 없이 관리된다
- 커널 스레드는 운영체제에 의해 직접 지원되고 관리된다
- 다중 스레드 모델은 다대일 모델, 일대일 모델, 다대다 모델이 있다
04-4 스레드 라이브러리
- 오늘날 많이 사용되는 쓰레드 라이브 러리는 POSIX Pthreads( Linux 계열 ), Windows thread, Java thread( 운영체제에 종속적, 06 : 55 )가 있다
04-5 암묵적 스레딩 (Implicit Threading)
- 스레딩의 생성과 관리 책임을 개발자로부터 컴파일러와 실행시간 라이브러리에게 넘겨주는 것을 암묵적 스레딩이라고 부른다
- 스레드 풀의 기본 아이디어는 프로세스를 시작할 때 아예 일정한 수의 스레드들을 미리 풀로 만들어두는 것이다
- OpenMP는 C, C++ 또는 FORTRAN으로 작성된 API와 컴파일러 디렉티브의 집합이다 OpenMP는 공유 메모리 환경에서 병렬 프로그래밍을 할 수 있도록 도움을 준다 개발자는 자신들의 코드 중 병렬 영역에 컴파일러 디렉티브를 삽입한다 이 디렉티브는 OpenMP 실행시간 라이브러리에 해당 영역을 병렬로 실행하라고 지시한다
Chapter 05 CPU 스케쥴링
05-1 기본 개념
- 다중 프로그래밍의 목적은 CPU 이용률을 최대화하기 위해 항상 실행 중인 프로세스를 가지게 하는 데 있다
- 프로세스 실행은 CPU 버스트로 시작되고 뒤이어 I/O 버스트가 발생한다
- 운영체제는 준비 큐에 있는 프로세스 중에서 하나를 선택해 실행해야 한다 선택 절차는 CPU 스케쥴러에 의해 수행된다
- 준비 큐는 반드시 FIFO 방식의 큐가 아니어도 되는 것에 유의하자
- 스케쥴링 방법에는 선점, 비선점이 있다
- 디스패처의 역할 1 : 한 프로세스에서 다른 프로세스로 문맥을 교환하는 일
- 디스패처의 역할 2 : 사용자 모드로 전환하는 일
- 디스패처의 역할 3 : 프로그램을 다시 시작하기 위해 사용자 프로그램의 적절한 위치로 이동하는 일
- 디스패처가 하나의 프로세스를 정지하고 다른 프로세스의 수행을 시작하는데까지 소요되는 시간을 디스패치 지연이라고 한다
- 자발적 문맥교환은 현재 사용 불가능한 자원을 요청했기 때문에 프로세스가 CPU 제어를 포기한 경우 발생한다 비자발적 문맥 교환은 타임 슬라이스가 만료되었거나 우선순위가 더 높은 프로세스에 의해 선점된 경우와 같이 CPU를 빼앗겼을 때 발생한다
05-2 스케쥴링 기준
- CPU 이용률, 처리량, 총처리 시간, 대기 시간, 응답 시간
- 총처리 시간 : 총처리 시간은 준비 큐에서 대기한 시간, CPU에서 실행하는 시간, 그리고 I/O 시간을 합한 시간이다
- 대기 시간 : 대기 시간은 준비 큐에서 대기하면서 보낸 시간의 합이다
05-3 스케쥴링 알고리즘
- CPU 스케줄링은 준비 큐에 있는 어느 프로세스에 CPU 코어를 할당할 것인지를 결정하는 문제를 다룬다
- FCFS, 이 방법에서는 CPU를 먼저 요청하는 프로세스가 CPU를 먼저 할당받는다
- Gantt 차트는 참여한 각 프로세스의 시작 시각과 종료 시각을 포함하여 특정 스케줄 기법을 도시하는 막대형 차트이다
- 모든 다른 프로세스들이 하나의 긴 프로세스가 CPU를 양도하기를 기다리는 것을 호위 효과(convoy effect)라고 한다
- SJF, CPU가 이용가능해지면 가장 작은 다음 CPU 버스트를 가진 프로세스에 할당한다
- SJF 알고리즘이 최적이긴 하지만, 다음 CPU 버스트의 길이를 알 방법이 없기 때문에 CPU 스케줄링 수준에서는 구현할 수 없다
- 다음 CPU 버스트는 일반적으로 측정된 이전의 CPU 버스트들의 길이를 지수 평균한 것으로 예측한다
- SJF 알고리즘은 선점형이거나 또는 비선점형일 수 있다 앞의 프로세스가 실행되는 동안 새로운 프로세스가 준비 큐에 도착하면 선택이 발생한다
- 선점형 SJF 알고리즘은 때때로 최소 잔여 시간 우선 스케쥴링(SRTF)이라고 불린다
- 라운드 로빈(RR) 스케쥴링 알고리즘은 시간 할당량 또는 타임슬라이스 라고 하는 작은 단위의 시간을 정의한다, CPU 스케쥴러는 준비 큐를 돌면서 한 번에 한 프로세스에 한 번의 시간 할당량 동안 CPU를 할당한다
- RR 알고리즘의 성능은 시간 할당량의 크기에 매우 많은 영향을 받는다 그러므로 우리는 시간 할당량이 문맥 교환 시간과 비교해 더 클 것을 원한다, 시간 할당량이 문맥 교환 시간에 비해 커야 하지만 너무 커서는 안된다
- 선점형 우선순위 스케줄링 알고리즘은 새로 도착한 프로세스의 우선순위가 현재 실행되는 프로세스의 우선순위보다 높다면 CPU를 선점한다
- 비선점형 우선순위 스케줄링 알고리즘은 단순히 준비완료 큐의 머리 부분에 새로운 프로세스를 넣는다
- 우선순위 스케줄링 알고리즘의 주요 문제는 무한 봉쇄 또는 기아 상태이다
- 실행 준비는 되어 있으나 CPU를 사용하지 못하는 프로세스는 CPU를 기다리면서 봉쇄된 것으로 간주할 수 있다
- 낮은 우선순위의 프로세스들이 무한히 봉쇄되는 문제에 대한 한 가지 해결 방안은 노화(aging)이다
- 노화(aging)는 오랫동안 시스템에서 대기하는 프로세스들의 우선순위를 점진적으로 증가시킨다
- 다단계 큐라고 하는 이 방법은 우선순위 스케줄링이 라운드 로빈과 결합한 경우에도 효과적이다
- 다단계 큐에서 우선순위가 가장 높은 큐에 여러 프로세스가 있는 경우 라운드 로빈 순서로 실행된다
- 다단계 피드백 큐 스케줄링 알고리즘에서는 프로세스가 큐들 사이를 이동하는 것을 허용한다 ( 기아를 방지하기 위해 우선순위가 낮은 큐에서 너무 오래 대기하는 프로세스가 점차 우선순위가 높은 프로세스로 이동될 수 있다 )
- 다단계 피드백 큐 스케줄러의 정의에 의하면 이 스케줄링 알고리즘은 가장 일반적인 CPU 스케줄링 알고리즘이다
05-4 스레드 스케줄링
- 대부분 최신 운영체제에서는 스케줄 되는 대상은 프로세스가 아니라 커널 수준 스레드이다
- 사용자 수준 스레드는 스레드 라이브러리에 의해 관리되고 커널은 그들의 존재를 알지 못한다
05-6 실시간 CPU 스케줄링
- 실시간 운영체제에서 CPU를 스케줄링 할 때는 특별한 쟁점을 고려해야 한다 일반적으로 soft 실시간 시스템과 hard 실시간 시스템으로 구분한다
Chapter 06 동기화 도구들
06-1 배경
- 협력적 프로세스는 논리 주소 공간(즉, 코드 및 데이터)을 직접 공유하거나 공유 메모리 또는 메시지 전달을 통해서만 데이터를 공유할 수 있다 그러나 공유 데이터를 동시에 접근하면 데이터의 일관성을 망칠 수 있다
- 본 장에서 프로세스가 병행 또는 병렬로 실행될 때 여러 프로세스가 공유하는 데이터의 무결성에 어떤 문제를 일으키는지에 관해 설명한다
- 문장 count++는 기계어(일반적인 기계에서)로 구현될 수 있음에 유의하라
- count++와 count– 문장을 병행하게 실행하는 것은 앞에서 제시한 저수준의 문장들을 임의의 순서로 뒤섞어 순차적으로 실행하는 것과 동등하다(그러나 각 고수준 문장 내에서의 순서는 유지된다)
- 부정확한 상태에 도달하는 것은 두 개의 프로세스가 동시에 변수 count를 조작하도록 허용했기 때문이다
- 실행 결과가 접근이 발생한 특정 순서에 의존하는 상황을 경쟁 상황(race condition)이라고 한다
- 본 장의 많은 부분은 협력하는 프로세스 간의 프로세스 동기화와 조정에 할애된다
06-2 임계구역 문제
- 한 프로세스가 자신의 임계구역에서 수행하는 동안에는 다른 프로세스들은 그들의 임계구역에 들어갈 수 없다는 사실을 기억하자
- 임계구역 문제에 대한 해결안은 다음의 세가지 요구 조건을 충족해야 한다 ( 상호 배제, 진행(No deadlock), 한정된 대기(No starvation) )
- 운영체제 내에서 임계구역을 다루기 위해서 선점형 커널과 비선점형 커널의 두 가지 일반적인 접근법이 사용된다( 일반적으로 선점형 커널이 선호됨 )
06-3 Peterson의 해결안
- Peterson의 해결안은 현대 컴퓨터 구조상에서 올바르게 실행된다고 보장할 수 없다
- Peterson의 해결안은 이론적으로 상호 배제, 진행, 한정된 대기의 요구조건을 만족시킨다
- Peterson의 해결안은 임계구역과 나머지 구역을 번갈아 가며 실행하는 두 개의 프로세스로 한정된다
- Peterson의 해결안이 올바르게 실행된다고 보장할 수 없는 이유는 최신 컴퓨터 아키텍처에서 시스템 성능을 향상하기 위해 프로세서 및 컴파일러가 종속성이 없는 읽기 및 쓰기 작업을 재정렬 할 수 있기 때문이다
06-4 동기화를 위한 하드웨어 지원
- 많은 현대 기계들은 한 워드(word)의 내용을 검사하고 변경하거나, 두 워드의 내용을 원자적으로 교환(swap)할 수 있는, 즉 인터럽트 되지 않는 하나의 단위로서, 특별한 하드웨어 명령어들을 제공한다 우리는 이들 특별한 명령어들을 사용하여 임계구역 문제를 상대적으로 간단한 방식으로 해결할 수 있다
- test_and_set() 명령어의 특징은 이 명령어가 원자적(atomically)으로 실행된다는 점이다
- compare_and_swap() 명령어(CAS)는 test_and_set() 명령어와 마찬가지로 두 개의 워드에 대해 원자적인 연산을 하지만 두 워드의 내용 교환에 기반을 둔 다른 기법을 사용한다
- 일반적으로 compare_and_swap() 명령어는 상호 배제를 제공하기 위해 직접 사용되지 않는다 오히려 임계구역 문제를 해결하는 다른 도구를 구축하기 위한 기본 구성요소로 사용된다 그러한 도구 중 하나는 원자적 변수로, 정수 및 부울과 같은 기본 데이터 유형에 대한 원자적 연산을 제공한다
- 원자적 변수는 원자적 갱신을 제공하지만 모든 상황에서 경쟁 조건을 완벽히 해결하지 않는다
06-5 Mutex Locks
- 우리는 임계구역을 보호하고, 따라서 경쟁 조건을 방지하기 위해 mutex 락을 사용한다 즉 프로세스는 임계구역에 들어가기 전에 반드시 락을 획득해야 하고 임계구역을 빠져나올 때 락을 반환해야 한다
- Mutex 락의 단점은 바쁜 대기(busy waiting)를 해야 한다는 것이다
- Mutex 락 유형을 스핀락(spinlock) 이라고도 한다 락을 사용할 수 있을 때까지 프로세스가 회전하기 때문이다
- 스핀락은 프로세스가 락을 기다려야하고 문맥 교환에 상당한 시간이 소요될 때 문맥 교환이 필요하지 않다는 장점이 있다
- 다중 코어 시스템의 특정 상황에서는 실제로 락이 필요할 때 스핀락이 선호된다
06-6 세마포
- 세마포 S는 정수 변수로서, 초기화를 제외하고는 단지 두 개의 표준 원자적 연산 wait()와 signal()로만 접근할 수 있다
- 운영체제는 종종 카운팅과 이진 세마포를 구분한다
- 카운팅 세마포의 값은 제한 없는 영역을 갖는다
- 이진 세마포의 값은 0과 1사이의 값만 가능하다 따라서 이진 세마포는 mutex 락과 유사하게 동작한다
- 세마포는 가용한 자원의 개수로 초기화된다 각 자원을 사용하려는 프로세스는 세마포에 wait() 연산을 수행하며, 이때 세마포의 값은 감소한다 프로세스가 자원을 방출할 때는 signal() 연산을 수행하고 세마포는 증가하게 된다 세마포의 값이 0이 되면 모든 자원이 사용 중임을 나타낸다
06-7 모니터
- 세마포는 자칫 잘못 사용하면 발견하기 어려운 타이밍 오류를 야기할 수 있는데 이러한 상황은 순수한 프로그래밍 오류 또는 비협조적인 프로그래머에 의해 야기된다
- 이러한 오류를 처리하기 위한 한 가지 전략은 간단한 동기화 도구를 통합하여 고급 언어 구조물을 제공하는 것이다 이 절에서는 근본적인 고급 언어 구조물 중 하나인, 모니터형을 설명한다
- 모니터 형은 모니터 내부에서 상호 배제가 보장되는 프로그래머가 정의한 일련의 연산자 집합을 포함하는 ADT이다
- 모니터 구조물은 모니터 안에 항상 하나의 프로세스만이 활성화되도록 보장해 준다 그러므로 프로그래머들은 이와 같은 동기화 제약 조건을 명시적으로 코딩해야 할 필요가 없다
- 이 동기화 기법들은 condition이라는 구조물로 제공될 수 있다
06-8 라이브니스
- 무기한 대기는 진행 및 한정된 대기 두 개의 기준을 위반한다
- 라이브니스는 프로세스가 실행 수명주기 동안 진행되는 것을 보장하기 위해 시스템이 충족해야 하는 일련의 속성을 말한다
- 한 집합 내의 모든 프로세스가 그 집합 내의 다른 프로세스만이 유발할 수 있는 이벤트를 기다릴 때, 이 프로세스들의 집합이 교착 상태에 있다고 말한다
- 통상 커널 데이터는 락에 의해 보호되기 때문에 낮은 우선순위 프로세스가 자원의 사용을 마칠 때까지 높은 우선순위 프로세스가 기다려야 한다
- 예를들어 우선순위가 L < M < H 순서인 L, M, H 세 개의 프로세스가 존재한다고 가정하자 이때 간접적으로 낮은 우선순위 프로세스(프로세스 M)는 프로세스 H가 L이 자원을 양도할 때까지 기다려야 하는 시간에 영향을 주게된다 이 라이브니스 문제는 우선순위 역전(priority inversion) 문제로 알려져 있으며, 이 문제는 셋 이상의 우선순위를 가진 시스템에서만 발생한다
- 통상 우선순위 역전 문제는 우선순위 상속 프로토콜을 구현하여 해결한다
Chapter 07 동기화 예제
07-1 고전적인 동기화 문제들
- 본 절에서는 많은 클래스의 병행 제어(concurrency control) 문제에 대한 예로서 중요한 여러 가지의 다른 동기화 문제들을 제시한다
- writer가 쓰기 작업 동안에 공유 데이터베이스에 대해 배타적 접근 권한(한 순간에 하나의 쓰레드만 접근)을 가지게 할 필요가 있다 이 동기화 문제를 readers-writers 문제라고 한다
- Readers-Writers 문제에는 여러 가지 변형들이 있는데 모두 우선순위와 연관된 변형들이다
- Readers-Writers 문제 첫번째, writer가 공유 객체를 사용할 수 있는 허가를 아직 얻지 못했다면, 어느 reader도 기다리게 해서는 안 된다
- Readers-Writers 문제 두번째, writer가 객체에 접근하려고 기다리고 있다면, 새로운 reader들은 읽기를 시작하지 못한다
- 위의 문제에 대한 해결안이 기아 문제를 낳을 수 있음에 유의해야 한다
- Reader-writer 락은 아래와 같은 상황에서 가장 유용하다
- 첫째, 공유 데이터를 읽기만 하는 프로세스와 쓰기만 하는 스레드를 식별하기 쉬운 응용
- 둘째, Writer보다 reader의 개수가 많은 응용, 일반적으로 reader-writer 락을 설정하는 데에 드는 오버헤드가 세마포나 상호 배제 락을 설정할 때보다 크다, 이 오버헤드는 동시에 여러 reader가 읽게 하여 병행성을 높임으로써 상쇄할 수 있다
- 식사하는 철학자들 문제는 고전적인 동기화 문제로 간주되는데, 병행 제어 문제의 한 예이기 때문이다, 그것은 교착 상태와 기아를 발생시키지 않고 여러 스레드에게 여러 자원을 할당해야 할 필요를 단순하게 표현한 것이다
- 식사하는 철학자들 문제를 세마포 해결안으로 해결할 수 없는 이유는 인접한 두 철학자가 동시에 식사하지 않는다는 것을 보장하지만, 교착상태를 야기할 가능성이 있기 때문에 채택할 수 없다
- 식사하는 철학자들 문제 해결을 위한 모니터 해결안은 철학자가 양쪽 젓가락 모두 얻을 수 있을 때만 젓가락을 집을 수 있다는 제한을 강제한다
07-5 대체 방안들
- 본 절에서는 스레드-안전 병행 응용 설계에 도움을 줄 수 있는 프로그래밍 언어와 하드웨어의 다양한 기능을 살펴본다
- 메모리 트랜잭션은 메모리 읽기와 쓰기 연산의 원자적인 연속적 순서이다, 락 대신 이러한 기법을 사용하는 이점은 개발자가 아니라 트랙잭션 메모리 시스템이 원자성을 보장할 책임이 있다는 것이다, 또한 락이 전혀 사용되지 않기 때문에 교착 상태가 발생하는 것이 불가능하다
- OpenMp가 가지는 장점은 스레드의 생성과 관리가 OpenMP 라이브러리에 의해서 처리되어 응용 개발자들은 신경 쓰지 않아도 된다는 것이다
- OpenMp가 가지는 단점은 응용 개발자가 가능한 경쟁 조건을 직접 발견해 내야만 하고 컴파일러 디렉티브를 이용하여 공유 메모리를 직접 보호해야 한다는 것이다 또한 여전히 교착 상태가 발생할 수 있다
- 함수형 언어는 변경 가능 상태를 허용하지 않기 때문에 경쟁 조건이나 교착 상태와 같은 쟁점에 대해 신경 쓸 필요가 없다
Chapter 08 교착 상태
08-1 시스템 모델
- 대기 중인 스레드들이(그들이 요청한 자원들이 다른 스레드들에 의해서 점유되어 있고 그들도 다 대기 상태에 있기 때문에) 결코 다시는 그 상태를 변경시킬 수 없으면 이런 상황을 교착 상태라 부른다
- 보통 운영체제들은 교착 상태 예방 기능을 제공하지 않는다 따라서 교착 상태가 없는 프로그램을 설계하는 것은 전적으로 프로그래머의 책임으로 남는다
- 시스템은 경쟁하는 스레드들 사이에 분배되어야 할 유한한 수의 자원들로 구성된다
08-2 다중 스레드 응용에서의 교착 상태
- 스레드가 서로 원하는 뮤텍스 락이 다른 상황에서 교착 상태가 발생한다 ( P.352 )
08-3 교착 상태 특성
- 교착 상태는 한 시스템에 다음 네 가지 조건이 동시에 성립될 때 발생할 수 있다 ( 상호 배제, 점유하며 대기, 비선점, 순환 대기 )
- 자원 할당 그래프에 사이클이 없다면, 시스템은 교착 상태가 아니다 반면에 사이클이 있다면 시스템은 교착 상태일 수도 있고 아닐 수도 있다
08-5 교착 상태 예방
- 교착 상태가 발생하려면 필요한 네 가지 필요조건 중에서 최소한 하나가 성립하지 않도록 보장함으로써, 우리는 교착 상태의 발생을 예방할 수 있다
- 일반적으로 상호 배제 조건을 거부함으로써 교착 상태를 예방하는 것은 불가능하다 어떤 자원들은 근본적으로 공유가 불가능하기 때문이다
- 점유하며 대기 조건이 성립되지 않게 하기위해 스레드가 자원을 전혀 갖고 있지 않을 때만 자원을 요청할 수 있도록 허용한다 스레드는 일부 자원을 요청하고 사용할 수도 있다 스레드가 추가의 자원을 요청할 수 있으려면, 자신에게 할당된 모든 자원을 반드시 먼저 방출해야 한다
- 비선점 조건이 성립되지 않게 하기위해 만일 어떤 자원을 점유하고 있는 스레드가 즉시 할당할 수 없는 다른 자원을 요청하면(즉, 스레드가 반드시 대기해야 하면), 현재 점유하고 있는 모든 자원이 선점된다 즉, 이들 자원들이 묵시적으로 방출된다 이 프로토콜은 CPU 레지스터나 데이터베이스 트랜잭션처럼 그 상태가 쉽게 저장되고 후에 복원될 수 있는 자원에 종종 적용 되지만 mutex 락과 세마포같은 자원에는 적용될 수 없다
- 순환대기 조건이 성립되지 않게 하기위해 모든 자원 유형에 전체적인 순서를 부여하여, 각 프로세스가 열거된 순서대로 오름차순으로 자원을 요청하도록 요구할 수 있다 이 방법을 사용하면 순환 대기 조건이 발생하지 않는다 그러나 순서나 계층 구조를 정하는 것 자체만으로는 교착 상태를 예방할 수 없다는 것을 유의하자 순서를 지키는 프로그램을 작성하는 것은 응용 프로그래머에게 달려 있다
08-6 교착 상태 회피
- 각스레드의 요청과 방출에 대한 완전한 순서를 파악하고 있다면, 우리는 각 요청에 대해서 가능한 미래의 교착 상태를 피하고자 스레드가 대기해야 하는지 여부를 결정할 수 있다
- 시스템 상태가 안전하다는 말은 시스템이 어떤 순서로든 스레드들이 요청하는 모든 자원을(최대 요구 수를 요구하더라도) 교착 상태를 야기시키지 않고 차례로 모두 할당해 줄 수 있다는 것을 뜻한다 즉 시스템이 안전 순서를 찾을 수 있다면 시스템은 안전하다고 말한다
- 모든 스레드를 무사히 마칠 수 있는 시퀀스를 찾을 수 없으면 불안전하다고 한다
- 시스템이 안전 상태에 머무는 한 운영체제는 불안전 상태나 교착 상태 모두를 예방할 수 있다
- 회피 알고리즘의 기본 원칙은 시스템의 상태가 항상 안전 상태를 떠나지 않도록 고수하는 것이다
- 사이클 탐지 알고리즘을 이용해 안전성을 검사할 수 있다
- 은행원 알고리즘은 고객들이 현금을 찾으러 와도 일정한 순서에 의해 모든 고객의 요청을 다 들어줄 수 있다
- 은행원 알고리즘에 대한 자세한 내용은 영상 참조 ( 11 : 50 )
- 은행원 알고리즘, 안정성 알고리즘, 시스템이 안전한지 아닌지를 알아낼 수 있는 알고리즘 이다
- 은행원 알고리즘, 자원 요청 알고리즘, 자원 요청이 안전하게 들어줄 수 있는지를 검사하는 알고리즘 이다
08-7 교착 상태 탐지
- 교착 상태를 탐지하기 위해 시스템은 대기 그래프를 유지할 필요가 있고, 주기적으로 그래프에서 사이클을 탐지하는 알고리즘을 호출한다
08-8 교착 상태로부터 회복
- 시스템이 교착 상태로부터 회복하게 하는 방법은 아래와 같이 두가지가 있다
- 첫째, 순환 대기를 깨뜨리기 위해 단순히 한 개 이상의 스레드를 중지시키는 것이다
- 두번째, 교착 상태에 있는 하나 이상의 스레드들로부터 자원을 선점하는 것이다
Chapter 09 메인 메모리
09-1 배경
- CPU는 PC(program counter)가 지시하는 대로 메모리로 부터 다음 수행할 명령어를 가져온다
- 메인 메모리와 각 처리 코어에 내장된 레지스터들은 CPU가 직접 접근할 수 있는 유일한 범용 저장장치이다
- 기준 레지스터는 가장 작은 합법적인 물리 메모리 주소의 값을 저장하고, 상한 레지스터는 주어진 영역의 크기를 저장한다
- 사용자 모드에서 수행되는 프로그램이 운영체제의 메모리 공간이나 다른 사용자 프로그램의 메모리 공간에 접근하면 운영체제는 치명적인 오류로 간주하고 트랩을 발생시킨다
- 컴파일러는 심볼 주소를 재배치 가능 주소로 바인딩시키고, 다음에 링커나 로더가 재배치 가능 주소를 절대 주소로 바인딩 시킨다
- CPU가 생성하는 주소를 일반적으로 논리 주소라 하며, 반면에 메모리가 취급하게 되는 주소(메모리 주소 레지스터, MAR에 주어지는 주소)를 물리 주소라 한다
- 프로그램에 의해 생성된 모든 논리 주소 집합을 논리 주소 공간이라 하며 이 논리 주소와 일치하는 모든 물리 주소 집합을 물리 주소 공간이라 한다
- 프로그램의 실행 중에는 가상 주소를 물리 주소로 바꾸어줘야 하는데 이 변환 작업은 하드웨어 장치인 메모리 관리 장치(MMU)에 의해 실행된다
- 메모리 공간의 더 효율적 이용을 위해서는 동적 적재를 해야한다, 동적 적재에서 각 루틴은 실제 호출되기 전까지는 메모리에 올라오지 않고 재배치 가능한 상태로 디스크에서 대기하고 있다
- 동적 연결 라이브러리는 사용자 프로그램이 실행될 때, 사용자 프로그램에 연결되는 시스템 라이브러리이다
09-2 연속 메모리 할당
- 연속적인 메모리 할당에서 각 프로세스는 다음 프로세스가 적재된 영역과 인접한 하나의 메모리 영역에 적재된다
- 가변 파티션 기법에서 운영체제는 사용 가능한 메모리 부분과 사용 중인 부분을 나타내는 테이블을 유지한다, 사용 가능한 메모리 블록은 hole로 간주한다
- 동적 메모리 할당 문제 해결책은 최초 적합, 최적 적합, 최악 접합이 있다
- 최초 적합 전략과 최적 적합 전략 모두 외부 단편화로 인해 어려움을 겪는다 이는 유후 공간들을 모두 합치면 충분한 공간이 되지만 그것들이 너무 작은 조각들로 여러 곳에 분산되어 있을 때 발생한다
- 일반적으로는 메모리를 먼저 아주 작은 공간들로 분할하고 프로세스가 요청하면 할당을 항상 이 분할된 크기의 정수배로만 해주는 것이 보통이다 이 경우 할당된 공간은 요구된 공간보다 약간 더 클 수 있다 이들 두 크기 사이의 남는 부분이 바로 내부 단편화이다
- 외부 단편화 문제를 해결할 수 있는 방법중 하나는 한 프로세스의 논리 주소 공간을 여러 개의 비연속적인 공간으로 나누어 필요한 크기의 공간이 가용해지는 경우 물리 메모리를 프로세스에 할당하는 방법이다 이것은 컴퓨터 시스템에 가장 일반적인 메모리 관리 기법인 페이징에서 사용되는 전략이다
09-3 페이징
- 페이징은 연속 메모리 할당을 괴롭히는 두 가지 문제인 외부 단편화와 관련 압축의 필요성을 피한다
- 물리 메모리는 프레임이라 불리는 같은 크기 블록으로 나누어진다
- 논리 메모리는 페이지라 불리는 같은 크기의 블록으로 나누어진다
- CPU에서 나오는 모든 주소는 페이지 번호와 페이지 오프셋 두개의 부분으로 나누어진다
- 페이지 번호는 프로세스 페이지 테이블을 액세스할 때 사용된다
- 모든 논리 주소는 페이징 하드웨어에 의해 실제 주소로 바인딩 된다
- 페이징 기법을 사용하면 외부 단편화가 발생하지 않는다 모든 놀고 있는 프레임이 프로세스에 의해 할당될 수 있기 때문이다 그러나 이제는 내부 단편화가 발생한다
- 페이지 크기가 작아지면 그에 반비례하여 페이지 테이블의 크기가 커지게 되고 이 테이블이 차지하는 공간은 낭비된다
- 운영체제는 물리 메모리를 관리하기 때문에 물리 메모리의 자세한 할당에 대해 파악하고 있어야 한다 이런 정보는 일반적으로 프레임 테이블 이라는 시스템에 하나밖에 없는 자료구조에 있다
- 대부분의 컴퓨터는 페이지 테이블을 메인 메모리에 저장하고 페이지 테이블 기준 레지스터(PTBR)로 하여금 페이지 테이블을 가리키도록 한다 다른 페이지 테이블을 사용하려면 단지 이 레지스터만을 변화시키면 되고, 따라서 문맥 교환 시간을 줄일 수 있다
- 메인 메모리에 페이지 테이블을 저장하면 문맥 교환 속도가 빨라지지만 메모리 엑세스 시간이 느려질 수도 있다 이 문제에 대한 해결에는 TLB라고 불리는 특수한 소형 하드웨어 캐시가 사용된다
- 접근하려는 메모리의 페이지 번호가 TLB에서 발견되는 비율을 적중률이라고 부른다
- 페이징 환경에서 메모리 보호는 각 페이지에 붙어있는 보호 비트에 의해 구현된다 이 비트들은 보통 페이지 테이블에 속해 있다
- 비트가 무효로 설정된 것을 발견하면 트랩이 발생된다
- 페이징의 장점은 공통의 코드를 공유할 수 있다는 점이다
09-4 페이지 테이블의 구조
- 이번 절에서는 페이지 테이블을 구성하는 가장 일반적인 방법을 소개한다
- 계층적 페이징, 테이블을 여러 개의 작은 조각으로 나누는것
- 해시 페이지 테이블, 가상 주소를 해시로 사용하는 기법
- 역 페이지 테이블, 메모리 프레임마다 한 항목씩 할당한다 각 항목은 그 프레임에 올려와 있는 페이지 주소, 그리고 그 페이지를 소유하고 있는 프로세스 ID를 표시한다
09-5 스와핑
- 프로세슨 또는 프로세스의 일부분은 실행 중에 임시로 백업 저장장치로 내보내어 졌다가 실행을 계속하기 위해 다시 메모리로 되돌아 올 수 있다
- 기본 스와핑, 메인 메모리와 백업 저장장치 간에 전체 프로세스를 이동한다
- 페이징에서의 스와핑, 대부분의 시스템은 프로세스 전체가 아닌 프로세스 페이지를 스왑할 수 있는 변형 스와핑을 사용한다 이 전략은 여전히 물리 메모리를 초과 할당할 수 있지만 프로세스 전체를 스왑하는 비용은 발생하지 않는다
Chapter 10 가상 메모리
10-1 배경
- 가상 메모리 라는 것은 프로세스 전체가 메모리 내에 올라오지 않더라도 실행이 가능하도록 하는 기법이다 이 기법의 주요 장점 중 하나는 사용자 프로그램이 물리 메모리보다 커져도 된다는 점이다
- 가상 메모리는 실제의 무리 메모리 개념과 개발자의 논리 메모리 개념을 분리한 것이다
- 논리 메모리를 물리 메모리로부터 분리해주는 것 외에 가상 메모리는 페이지 공유를 통해 파일이나 메모리가 둘 또는 그 이상의 프로세스들에 의해 공유되는 것을 가능하게한다
10-2 요구 페이징
- 요구 페이징 가상 메모리를 사용하면 프로그램 실행 중 필요한 때만 페이지가 적재된다
- 프로세스가 메모리에 올라와 있지 않은 페이지에 접근하려고 하면 페이지 테이블 항목이 무효로 설정되어 있으므로 페이지 폴트 트랩이 발생한다
- 순수 요구 페이징은 어떤 페이지가 필요해지기 전에는 결코 그 페이지를 메모리로 적재하지 않는 방법이다
- 참조의 지역성이라는 성질은 프로그램의 어느 한 특정 작은 부분만 한동안 집중적으로 참조하는 성질이다
- 요구 페이징을 위한 필수적인 요구 사항은 페이지 폴트 오류 처리 후에 명령어 처리를 다시 시작할 수 있어야 한다는 것이다
- 요구 페이징은 컴퓨터 시스템의 성능에 큰 영향을 줄 수 있다 왜 그런지 알아보기 위하여 요구 페이지 메모리에 대한 실질 접근 시간을 계산해보자
10-3 쓰기 시 복사
- 부모의 페이지들을 다 복사해오는 대신 쓰기 시 복사 방식을 사용할 수 있다 이 방식에서는 자식 프로세스가 시작할 때 부모의 페이지를 당분간 함께 사용하도록 한다
10-4 페이지 교체
- 페이지 폴트 서비스 루틴에서 페이지 교체시 희생될 프레임을 선정하기 위하여 페이지 교체 알고리즘을 적용한다
- 요구 페이징 시스템은 두 가지 중요한 문제를 해결해야 하는데, 그것은 프레임 할당 알고리즘과 페이지 교체 알고리즘이다
- 페이지 교체 알고리즘의 성능은 특정 메모리 참조 나열에 대해 알고리즘을 적용하여 페이지 폴트 발생 횟수를 계산하여 평가한다 이러한 메모리 주소의 나열을 참조열(reference string)이라 부른다
- FIFO 페이지 교체, 메모리에 올라온 지 가장 오래된 페이지를 내쫓는다
- 최적 페이지 교체, 앞으로 가장 오랫동안 사용되지 않을 페이지를 찾아 교체해라, 이 알고리즘의 실제 구현은 어렵다 왜냐하면 이 방식은 프로세스가 앞으로 메모리를 어떻게 참조할 것인지를 미리 알아야 하기 때문이다
- LRU 페이지 교체, 최근의 과거를 가까운 미래의 근사치로 본다면 가장 오랜 기간 동안 사용되지 않은 페이지를 교체할 수 있다 이 기법이 least-re-cently-used(LRU) 알고리즘이다
- LRU를 구현하는 방법에는 계수기를 활용하는 방법과 스택을 활용하는 방법이 있다
- LRU 페이지 교체 지원을 충분히 할 수 있는 하드웨어는 많지 않다 어떤 시스템에서는 전혀 하드웨어적인 지원을 하지 않고 다른 (FIFO와 같은) 알고리즘을 쓸 수 밖에 없다 그러나 많은 시스템은 참조 비트의 형태로 어느 정도의 지원은 하고 있다
- 2차 기회 알고리즘, 참조 비트가 0이면 페이지를 교체하고 1이면 다시 한번 기회를 주고 다음 FIFO 페이지로 넘어간다
10-5 프레임의 할당
- n개의 프로세스에 m개의 프레임을 분할하는 가장 쉬운 방법은 모두에 같은 몫 m/n 프레임씩 주는것이다 이러한 방법을 균등 할당 이라 한다
- 가용 메모리를 각 프로세스의 크기 비율에 맞추어 할당하는 방법인 비례 할당 방식을 사용할 수 있다
- 전역 교체는 프로세스가 교체할 프레임을 다른 프로세스에 속한 프레임을 포함한 모든 프레임을 대상으로 찾는 경우이다
- 지역 교체는 각 프로세스가 자기에게 할당된 프레임 중에서만 교체될 희생자를 선택할 수 있는 경우이다
10-6 스래싱
- 반복해서 페이지 폴트가 발생하며 교체된 페이지는 다시 얼마 지나지 않아 읽어올 필요가 생겨 과도한 페이징 작업을 하게 되는 현상을 스래싱 이라고 부른다
- 스래싱이 발생하면 실질 메모리 접근 시간은 증가하고 프로세스들은 페이징하는 데 시간을 다 소비하게 되어 아무런 일도 할 수 없게 된다
- 지역성 모델이란 프로세스가 실행될 때에는 항상 어떤 특정한 지역에서만 메모리를 집중적으로 참조함을 말한다
- 작업 집합 모델에서 페이지가 활발하게 사용되었으면 작업 집합에 포함된다 이 작업 집합은 프로그램 지역성의 근삿값이 된다
Chapter 11 대용량 저장장치 구조
11-1 대용량 저장장치 구조의 개관
- 최신 컴퓨터의 기본 대용량 저장장치 시스템은 보조저장장치이며 일반적으로 하드 디스크 드라이브(HDD) 및 비휘발성 메모리(NVM)장치를 사용하여 제공된다
- 일부 시스템에는 일반적으로 자기 테이프, 광디스크 또는 클라우드 저장장치로 구성된 느리고 더 큰 3차 저장장치가 있다
11-2 디스크 스케쥴링
- HDD의 경우 접근 시간을 최소화하고 전송 대역폭을 최대화하는 것이 목표이다
11-5 저장장치 관리
- 컴퓨터의 전원을 켜거나 재부팅 할 때와 같이 컴퓨터가 실행을 시작하려면 실행할 초기 프로그램이 존재해야 한다
- 대부분의 컴퓨터에서 부트스트랩은 시스템 마더보드의 NVM 플래시 메모리 펌웨어에 저장되며 알려진 메모리 위치에 매핑된다
11-8 RAID 구조
- 시스템이 많은 수의 드라이브를 가지고 있고, 그 시스템이 병렬적으로 운영된다면 데이터 읽기, 쓰기 비율을 향상할 수 있다 더욱이 중복 정보가 여러 드라이브에 저장되기 때문에 저장의 신뢰성을 높일 수 있다 그러므로 하나의 드라이브 오류로 데이터가 분실되지 않는다
- RAID라 불리는 다양한 디스크 구성 기술은 일반적으로 성능 향상과 신뢰성 이슈를 해결하는 데 역점을 두고 있다
- 패리티 비트와 디스크 스트라이핑을 결합하여 적은 비용으로 중복을 허용하는 많은 기법이 제안되었다 이러한 기법은 각기 다른 가격 대 성능 비를 가지고 있으며, RAID 레벨로 분류될 수 있다
Chapter 12 입출력 시스템
12-1 개관
- 컴퓨터의 두 가지 주요 작업은 계산과 입출력 작업이다
- 많은 경우 계산 혹은 연산 처리 작업은 부수적이며 입출력 작업이 더 중요하다
12-2 입출력 하드웨어
- 입출력 전송을 하기 위해 처리기는 어떻게 명령어와 데이터를 컨트롤러에 전달하는가, 대답은 간단하다 모든 컨트롤러는(제어용 또는 데어터용) 레지스터를 가지고 있다 본체의 프로세서는 이들 컨트롤러의 레지스터에 비트 패턴을 쓰거나 읽음으로써 입출력을 수행한다
- CPU는 물리 메모리에 사상된 장치-제어 레지스터를 읽고 쓸 때 표준 데이터 전송 명령을 사용함으로써 입출력 요청을 수행하게 된다
- 입출력 장치가 CPU에 자신의 상태 변화를 통보하는 하드웨어 기법을 인터럽트라고 한다
- DMA는 CPU의 도움 없이도 자신이 직접 버스를 통해 DMA 명령 블록을 액세스하여 입출력을 수행한다
12-3 응용 입출력 인터페이스
- 봉쇄형 시스템 콜을 하면, 호출 스레드는 봉쇄 상태로 들어가게 된다
- 비봉쇄형 읽기의 경우 그 시점에서 가지고 올 수 있는 데이터(그것이 전체 데이터이건, 일부이건) 가지고 즉각적으로 복귀한다
- 비동기식 읽기의 경우 입력이 완전히 끝난 후(시간이 좀 더 걸리더라도) 완전한 데이터를 전송해 달라고 요청한다
Chapter 13 파일 시스템 인터페이스
13-1 파일 개념
- 운영체제는 컴퓨터 시스템을 편리하게 사용하기 위해 저장된 정보에 대한 일관된 논리적 관점을 제공하고 저장장치의 물리적 특성을 추상화하여 논리적 저장 단위, 즉 파일을 정의한다
13-2 접근 방법
- 순차 접근, 디크스에 있는 파일을 마치 오디오의 카세트테이프를 재상하는 방식처럼 접근한다
- 직접 접근, 직접 접근을 위해서 파일은 고정 길이의 논리 레코드의 집합으로 정의되고 직접 접근 파일은 어떠한 블록이라도 직접 액세스할 수 있다
Chapter 14 파일 시스템 구현
14-1 파일 시스템 구조
- 파일 시스템은 아래와 같이 여러 층으로 이루어져 있다
14-4 할당 방법
- 주요 쟁점은 파일들을 어떻게 저장장치 공간에 배치해야 디스크 공간을 효율적으로 사용할 수 있고, 파일들을 빨리 접근할 수 있는가 이다
- 연속 할당은 각 파일이 저장장치 내에서 연속적인 공간을 차지하도록 요구한다
- 연결 할당은 연속 할당의 모든 문제를 해결한다 연결 할당의 경우 파일은 저장장치 블록의 연결 리스트 형태로 저장되고, 이 블록들은 장치 내에 흩어져 저장될 수 있다
- FAT 테이블은 각 블록마다 한 개의 항목을 가지고 있고 이 항목은 디스크 블록 번호를 인덱스로 찾는다
- 색인 할당은 색인 블록을 관리함으로써, FAT가 없으면 직접 접근 방식을 지원할 수 없는 문제를 해결한다
14-5 가용 공간의 관리
- 저장장치 공간은 제한되어 있기 때문에 삭제된 파일들이 차지하던 공간을 새로운 파일들을 위하여 다시 재사용하여야 한다 시스템은 이러한 가용 공간을 리스트로 유지하고 관리한다
Chapter 16 보안
16-1 보안 문제
- 보안은 시스템과 데이터의 무결성이 보존될 것이라는 확신의 척도이다
- 보호는 컴퓨터 시스템에 의해 정의된 자원에 대한 프로세스 및 사용자의 액세스를 제어하는 일련의 기법이다
- 위협(threat)은 취약성의 발견과 같은 보안 위반에 대한 잠재적 가능성인 반면 공격(attack)은 보안을 깨드리기 위한 시도이다
16-2 프로그램 위협
- 악성 코드는 컴퓨터 시스템을 악용, 비활성화 또는 손상하도록 설계된 소프트웨어이다
- 코드 인젝션 공격은 악의가 없는 선의의 소프트웨어라도 악용될 경우 공격자가 프로그램 코드를 장악하여 기존 코드 흐름을 바꾸거나 새로운 코드를 추가하여 완전히 다시 프로그래밍할 수 있는 취약점을 포함할 수 있다
- 바이러스는 자신을 복제하고 다른 프로그램을 감염 시키도록 고안된 프로그램이다
- 웜은 네트워크를 사용하여 인간의 도움 없이 복제한다
16-3 시스템과 네트워크 위협
- 공격자는 수동적인 상태를 유지하면서 네트워크 트래픽을 가로채는 것을 스니핑 공격이라고 한다
- 공격자가 활동적인 역할을 수행하여 당사자 중 하나로 위장하거나 전적으로 활동적인 중간자가 되어 두 피어 간의 트랜잭션을 가로채거나 수정하는 것을 스푸핑 이라고 한다
- 서비스 거부, 정보를 획득하거나 자원을 훔치는 것이 아니라, 시스템의 정당한 사용을 불가능하게 하는것이다
- 포트 스캐닝 자체는 공격이 아니라 해커가 시스템의 취약성을 탐지하는 수단이다
16-4 보안 도구로서 암호 기법
- 암호 기법은 메시지의 송신자와 수신자를 제한하는 데 사용된다
- 현대의 암호 기법은 네트워크의 컴퓨터들에 선택적으로 분배되어 메시지를 처리하는 데 사용되는 키라는 비밀에 기반을 두고 있다
- 암호화 알고리즘은 메시지의 발신자가 특정키를 소유한 컴퓨터만이 메시지를 읽는 것을 보장할 수 있도록 해주거나 데이터를 기록한 사람만이 데이터를 읽을 수 있다는 것을 보장해준다
- 대칭 암호화 알고리즘은에서 암호화 및 복호화에 같은 키가 사용된다
- 비대칭 암호화에서는 암호화와 복호화의 키가 다르다 여기에서 암호화된 통신을 받고자 하는 주체가 두 개의 키를 생성하여 그중 하나(공개 키라 불린다)를 누구든지 원하는 사람에게 공개한다
- RSA 암호 기법은 가장 널리 사용되는 비대칭 알고리즘이다
- 한 메시지의 잠재적 송신자의 집합을 제한하는 것을 인증이라 한다
- 인증 알고리즘의 두 번째 유형은 디지털 서명 알고리즘이다 따라서 생성된 인증자는 디지털 서명이라 불린다
- 디지털 서명 알고리즘은 아무나 메시지의 신빙성을 확인할 수 있게 하므로 대단히 유용하다
Chapter 17 보호
17-1 보호의 목표
- 운영체제 내의 프로세스들은 다른 프로세스들에 의한 활동으로부터 보호되어야 한다 이를 실현하는 방법은 운영체제로부터 적절한 권한을 부여받은 프로세스만 파일, 메모리 세그먼트, CPU, 네트워킹, 그 외 자원들을 대상으로 작업할 수 있도록 보장하는 것이다
17-2 보호의 원칙
- 보호를 위해 핵심적이며 오랜 시간에 걸쳐 확인된 지배 원칙으로 최소 권한의 원칙이 있다 ( 필요한 만큼의 권한만 부여하는 법칙이다 )
17-5 접근 행렬
- 일반적인 보호 모델은 추상적으로 접근 행렬 이라 불리는 하나의 행렬로 볼 수 있다
- 접근 행렬 기법은 여러 정책을 지정할 수 있는 기법을 우리에게 제공한다
17-11 기타 보호 개선 방법
- 샌드박싱은 할 수 있는 것을 제한하는 환경에서 프로세스를 실행하는 작업이 포함된다
- 코드 서명은 프로그램과 실행 파일의 디지털 서명으로 작성자가 프로그램을 만든 이후에 변경되지 않았음을 확인하는 것이다
댓글남기기