운영체제 01

‘Operating System Concepts 8th’를 정리한 글이다.

1.1 운영체제가 할 일

  • 하드웨어 : 중앙처리장치(CPU), 메모리 및 입출력(I/O) 등의 물리적 장치들
  • 응용 프로그램 : 워드프로세서, 컴파일러, 웹 브라우저 등의 소프트웨어
  • 운영체제 : 하드웨어를 제어하고 다양한 응용 프로그램간의 하드웨어 사용을 조정.

운영체제는 마치 정부처럼 그 자체로는 유용한 기능을 제공하기보다 다른 프로그램들이 유용한 작업을 할 수 있는 환경을 제공한다. 사용자 관점(User View)와 시스템 관점(System View)로 나눠서 살펴볼 수 있다.

1.1.1 사용자 관점

대부분의 컴퓨터 사용자는 PC를 독점하기에 이 때 운영체제는 다수 사용자의 요구사항을 만족시키기보다는 한 사용자가 사용하기에 적합하도록 최적화된다.

대형 컴퓨터나 미니 컴퓨터에 연결되어 여러 사용자가 사용할 경우에 운영체제는 자원 이용을 극대화하도록 설계된다. CPU, 메모리, IO등 모든 자원을 효율적으로 사용하게끔 한다.

자원의 이용 측면에 전혀 신경을 쓰는 경우와 최대한 효율적으로 사용시키는 식으로 목표가 달라진다.

일부 컴퓨터는 사용자 관점이 존재하지 않거나 매우 작은 경우도 있다. 예를 들면 가전제품이나 자동차 내의 내장형 컴퓨터는 숫자 키패드를 가지고 상태를 보이기 위해 표시등을 켜고 끄는 식이다.

한 마디로 사용자 관점에서 운영체제는 서비스를 제공해주는 역할을 하고 있다.

1.1.2 시스템 관점

컴퓨터 관점에서 운영체제는 자원 할당자(resource allocator)로 볼 수 있다. 컴퓨터는 문제를 해결하기 위해 여러 자원을 필요로 한다. CPU 시간, 메모리 공간, 파일 저장 공간, 입출력장치 등. 운영체제는 이들 자원의 관리자다.

자원에 대해 서로 상충될 수 있는 많은 요청이 있기에 운영체제는 컴퓨터 시스템을 효율적이고 공정하게 운영할 수 있게 하려 한다. 그렇기에 운영체제는 제어 프로그램(control program)이란 명칭이 붙는다.

1.1.3 운영체제의 정의

그렇다면 운영체제는 어떻게 정의할까? 운영체제에 대한 완벽한 정의는 없다.

컴퓨터가 존재하는 이유는 사람이 해결하려는 문제를 더 쉽게 해결하기 위함이다. 이 목적을 위해 컴퓨터 하드웨어가 개발되었다. 순수 하드웨어만으로는 사용하기 쉽지 않기에 응용 프로그램이 개발되었다.

이런 컴퓨터 시스템에서 발생하는 문제점을 해결하기 위한 합리적인 방법을 제공하는 것이 운영체제이다. 다양한 프로그램은 입출력 장치의 통제와 같은 공통적인 연산을 필요로 한다. 여기에 자원을 제어하고 할당하는 기능을 하나의 소프트웨어로 통합한 것이 운영체제이다.

1.2 컴퓨터 시스템의 구성

1.2.1 컴퓨터 시스템 동작

현재 컴퓨터 시스템은 공유 메모리에 대한 접근을 제공하는 공통 버스를 통해 연결된 여러 개의 장치 제어기와 하나 이상의 CPU로 구성된다

image
현대 컴퓨터 시스템

CPU와 장치 제어기는 메모리 사이클을 얻기 위해 경쟁하면서 병행 실행될 수 있다.

컴퓨터가 구동을 하기 위해서는 초기 프로그램을 가지고 있어야 한다. 이를 부트스트랩 프로그램이라 한다. 부트스트랩 프로그램은 운영체제의 커널을 찾아 메모리에 적재하고 “init”과 같은 첫 번째 프로세스를 실행한 후 event가 발생하기를 기다린다.

event가 발생하면 하드웨어나 소프트웨어로부터 발생한 인터럽트(interrupt)에 의해 신호가 보내진다.

하드웨어는 시스템 버스를 통해 CPU에 신호를 보내 인터럽트를 발생시킨다. 소프트웨어는 system call 혹은 모니터 호출이란 특별한 연산을 실행해서 인터럽트를 발생시킨다.

CPU가 인터럽트 되면 CPU는 하던 일을 중단하고 즉시 고정된 위치로 실행을 옮긴다. 그리고 인트럽트 서비스가 실행된다. 인터럽트 서비스 루틴이 완료되면 CPU는 이전에 했던 연산을 재개한다. 인터럽트 루틴은 반드시 실행되기 전의 상태를 저장하여야 한다. 그래서 복귀했을 때 인터럽트에 의해 중단되었던 연산이 인터럽트가 발생하지 않았던 것처럼 다시 시작된다.

1.2.2 저장장치 구조

CPU는 오직 메모리로부터 명령을 적재하고(load) 실행하는 프로그램은 모두 메모리에 저장(store)되어야 한다.

  • load : 주 메모리(RAM)로부터 CPU 내부의 레지스터로 한 워드를 옮긴다.
  • store : 레지스터의 내용을 주 메모리로 옮긴다.

근데 왜 명령을 load하고 store 하는가? 그냥 RAM에 프로그램과 데이터가 영구히 존재하면 좋을텐데, 그렇지 못 하는 이유는 다음과 같다.

  1. 주 메모리는 모든 필요한 프로그램과 데이터를 영구히 저장하기에는 너무 작다
  2. 주 메모리는 전원이 공급되지 않으면 그 내용을 잃어버리는 휘발성 저장장치다.

그렇기에 대부분의 컴퓨터 시스템은 보조 저장장치를 제공한다. 보조 저장장치의 주요 요건은 대량의 데이터를 영구히 보존할 수 있어야 한다.

컴퓨터 시스템에서 저장장치 시스템은 여러 계층으로 구성될 수 있다. 상위 수준은 가격이 비싸지만 빠르고 하위 수준은 가격이 싸지만 느리다.

image
저장 장치 구조

이렇게 구성되는 이유는 데이터가 공간적 지역성, 시간적 지역성을 갖기에 이렇게 구성한다.

1.2.3 입출력 구조

범용 컴퓨터 시스템은 공통 버스에 의해 연결된 여러 개의 장치 제어기와 CPU로 구성된다. 장치 제어기는 약간의 로컬 버퍼 저장장치와 특수 목적용 레지스터 집합을 유지한다.

제어기는 장치로부터 자신의 로컬 버퍼로 데이터 전송을 시작하고 그게 완료되면 인터럽트를 이용해서 디바이스 드라이버에게 알려준다. 디바이스 드라이버는 제어를 운영체제에게 반환한다.

근데 이 방식은 적은 양의 데이터를 전송할 때는 문제가 없지만 디스크 입출력 같은 대량의 데이터를 전송하는데엔 높은 오버헤드를 초래한다. 이 문제를 해결하기 위해 직접 메모리 접근(Direct memory Access, DMA) 장치를 사용한다.

DMA를 통해 CPU의 개입 없이 데이터 블록을 전송한다. 이러면 한 바이트마다 인터럽트가 발생하는 것이 아니라 블록 전송이 완료될 때마다 인터럽트가 발생하기에 CPU는 전송 작업을 실행하는 동안 다른 작업을 할 수 있다.

image
현대 컴퓨터 시스템 동작

1.3 컴퓨터 시스템 구조

1.3.1 단일처리기 시스템(Single Processor Systems)

대부분의 시스템이 사용하는 방식이다. 사용자 프로세스의 명령어를 포함하여 범용 명령어 집합을 실행할 수 있는 하나의 주 처리기를 가진다.

1.3.2 다중처리기 시스템(Multi Processor Systems)

처리기를 증가 시킨 시스템이다. 단일처리기보다 갖는 장점은 다음과 같다.

  1. 증가된 처리량(throughput) : 처리기가 증가했으니 짧은 시간 동안 더 많은 일을 할 수 있다. 그렇지만 N개의 처리기를 사용한다고 증가율이 N배가 되지 않고 N보다 작다. 다수의 처리기가 하나의 태스크를 위해 협력할 경우 모든 부분이 정확히 동작하도록 유지하기 위해 오버헤드가 유발되기 때문이다.
  2. 규모의 경제 : 다중처리기는 여러 개의 단일 시스템에 비해 비용을 절약할 수 있다. 주변장치, 대용량 저장장치, 전원 등을 공유하기 때문이다. 여러 컴퓨터가 각자 자신의 로컬 디스크와 많은 데이터의 복사본을 갖는 것보다 비용이 저렴한 것이다.
  3. 증가된 신뢰성 : 여러 개의 처리기에 적절하게 기능이 분산된다면 한 처리기가 고장나도 시스템이 고장나는게 아니라 속도만 느려지게 된다. 완전히 고장이 나는 것보다는 훨씬 안정적이다.

현재 사용하는 다중처리기는 두 가지 방식이 있다. 비대징척 다중처리는 하나의 주 처리기가 시스템을 제어한다. 주 처리기는 작업을 스케줄하고 다른 처리기들에게 작업을 할당시킨다. 대칭적 다중처리는 모든 처리기가 대등하다. 각 처리기는 자신 고유의 레지스터 집합과 사적인 지역적인 캐시를 가지고 있다. 그러나 모든 처리기는 물리메모리를 공유하고 있다.

1.3.3 클러스터형 시스템

여러 CPU를 가진 시스템의 또 다른 유형이 클러스터형 시스템이다. 다중처리기 시스템과 다른 점은 둘 이상의 독자적 시스템 또는 노드를 결합하여 구성한다는 점이다.(네트워크 연결을 의미)

클러스터가 네트워크로 연결된 여러 개의 컴퓨터 시스템으로 구성되기에 고성능 계산 환경을 제공하는데 이용될 수 있다.

image
클러스터 시스템 일반적 구조

1.4 운영체제의 구조

운영체제는 프로그램이 실행될 환경을 제공한다. 가장 중요한 측면은 다중 프로그램을 할 수 있는 능력이다. 일반적인 프로그램은 CPU 또는 입출력장치를 항상 바쁘게 유지할 수 없다. 어느 순간에는 입출력의 종료를 기다리는 것과 같이 어떤 일을 기다려야 한다. 이 때 운영체제는 다른 작업으로 전환해 CPU에게 일을 맡김으로써 CPU를 쉬지 않게 한다.

시분할 시스템에서는 CPU가 다수의 작업을 서로 교대로 실행하지만 매우 빠르고 빈번하게 교대가 일어나기 때문에 프로그램이 실행되는 동안 사용자들은 각자 자기의 프로그램과 상호작용할 수 있다.

시분할과 다중 프로그램 운영체제에서는 메모리에 여러 작업이 동시에 유지되어야 한다. 만약 몇몇 작업이 메모리로 옮겨올 준비가 되었고 그들 전부를 메모리에 보관할 공간이 불충분하다면, 시스템은 그들 중 몇 개를 선택해야 한다. 이러한 결정을 하는 것이 작업 스케줄링이다(5장에서 논의된다) 메모리에 여러 개의 프로그램이 동시에 있을 경우에 특정 형태의 메모리 관리가 필요하다(이건 8장, 9장에서 논의된다)

시분할 시스템에서 운영체제는 적절한 응답 시간을 보장하기 위해 작업들을 주 메모리에서 디스크로 적절하게 스왑인(swap-in) 또는 스왑아웃(swap-out) 시킨다. 이 목적을 달성할 수 있는 더 일반적인 방법은 가상 메모리를 사용하는 것인데, 이것은 일부만이 메모리에 있는 작업의 실행을 허용하는 기법이다. 이 기법의 주요한 이점은 프로그램이 물리 메모리의 크기보다 더 커도 된다는 것이다.

1.5 운영체제 동작

운영체제와 사용자는 컴퓨터 시스템의 하드웨어와 소프트웨어 자원을 공유하기 때문에 사용자 프로그램의 오류가 현재 실행 중인 프로그램에만 문제를 일으키도록 보장해야한다. 하나의 프로세스가 무한 루프에 빠진다고 다른 프로세스의 정상적인 동작을 방해할 수 있다.

이러한 오류에 대한 보호 기능이 없다면 컴퓨터 시스템은 항상 하나의 프로세스만 실행하거나 모든 출력 결과를 의심할 수 밖에 없다. 올바른 운영체제는 잘못된 또는 악의적인 프로그램 때문에 다른 프로그램이 부정확하게 실행되지 않는 걸 보장해야 한다.

1.5.1 이중 동작 모드

운영체제는 적어도 두 개의 독립된 동작 모드, 사용자 모드와 커널 모드(시스템 모드, 혹은 특권 모드)를 필요로 한다.

시스템 부팅 시 하드웨어는 커널 모드에서 시작된다. 이어 운영체제가 로딩되고 사용자 모드에서 사용자 프로세스가 시작된다. 트랩이나 인터럽트가 발생할 때마다 하드웨어는 사용자 모드에서 커널 모드로 전환한다. 즉 운영체제는 컴퓨터의 제어를 얻을 때마다 항상 커널 모드에 있으며 사용자 프로그램에게 제어를 넘기기 전에 항상 사용자 모드로 전환한다.

이런 이중 모드는 잘못된 사용자,프로그램으로부터 운영체제와 다른 프로그램을 보호하게 된다. 악 영향을 끼칠 수 있는 일부 명령들을 특권 명령으로 지정하고 이는 커널 모드에서만 작동할 수 있게 한다.

1.5.2 타이머

운영체제가 CPU에 대한 제어를 유지할 수 있도록 보장해야 한다. 사용자 프로그램이 무한 루프에 빠지거나, 시스템 서비스를 호출하지 않아서 제어가 운영체제로 복귀하지 않는 경우를 허용할 수는 없다. 이렇기에 타이머를 사용한다. 이 시간은 고정(예를 들면 1/60초) 혹은, 가변(1밀리에서 1초까지)일 수 있다.

운영체제는 사용자에게 제어를 양도하기 전에 타이머가 인터럽트를 할 수 있도록 설정 되었는지를 확인한다. 타이머가 인터럽트를 발생시키면 제어는 자동적으로 운영체제로 넘어가며, 운영체제는 이렇게 넘어온 인터럽트를 치명적인 오류로 취급하거나 프로그램에게 더 많은 시간을 줄 수 있다. 이 타이머 능력은 분명한 특권 명령이다.

1.6 프로세스 관리

프로그램은 명령이 CPU에 의해 실행되지 않으면 아무 일도 할 수 없다. 이렇게 실행 중인 프로그램을 프로세스라 한다. 프로세스는 자신의 일을 실행하기 위해 CPU 시간, 메모리, 파일, 입출력장치 등 여러 자원을 필요로 한다.

프로그램 그 자체는 프로세스가 아님을 강조한다. 프로그램은 디스크에 저장된 파일의 내용과 같이 수동적(passive) 개체인 반면, 프로세스는 다음 실행할 명령을 지정하는 프로그램 카운터(program counter)를 가진 능동적(active)인 개체다.

운영체제는 프로세스 관리와 연관해서 다음과 같은 활동에 책임을 진다

  • CPU에게 프로세스와 스레드 스케줄링
  • 사용자 프로세스와 시스템 프로세스의 생성과 제거
  • 프로세스의 일시 중지와 재실행
  • 프로세스 동기화를 위한 기법 제공
  • 프로세스 통신을 위한 기법 제공 (3~6장에 걸쳐 다시 논의된다)

1.7 메모리 관리

주 메모리는 일반적으로 CPU가 직접 주소를 지정할 수 있고, 직접 접근할 수 있는 유일한 대량 메모리이다.

프로그램이 실행되기 위해서는 반드시 절대 주소로 맵핑(mapping)되고 메모리에 적재되어야 한다. 프로그램을 실행하면서 이런 절대 주소를 생성하여 메모리의 프로그램 명령어와 데이터에 접근한다. 프로그램이 종료되고, 프로그램이 차지하던 메모리 공간은 가용공간으로 선언되어 다음 프로그램이 적재되어 실행할 수 있다.

메모리에 여러 개의 프로그램을 유지하기에 이를 위해 메모리 기법이 필요하다. 운영체제는 다음과 같은 일을 담당해야 한다.

  • 메모리의 현재 어느 부분이 사용되고 있으며, 누구에 의해 사용되고 있는지 추적
  • 어떤 프로세스(또는 그 일부)들을 메모리에 적재하고 제거할 것인지 결정
  • 필요에 따라 메모리 공간을 할당하고 회수 (8장~9장에서 논의한다)

1.8 저장장치 관리

1.8.1 파일 시스템 관리

운영체제는 테이프와 디스크 같은 대량 저장매체와 그것을 제어하는 장치를 관리함으로써 파일의 추상적인 개념을 구현한다. 파일에 접근하려고 할 때는 누구에 의해서, 그리고 어떤 방법으로(읽기, 쓰기, 첨가) 파일을 접근해야 하는가를 통제하는 것이 바람직하다.

운영체제는 파일 관리를 위해 다음과 같은 일을 담당한다.

  • 파일의 생성 및 제거
  • 디렉터리 생성 및 제거
  • 파일과 디렉터리를 조작하기 위한 프리미티브의 제공
  • 파일을 보조 저장장치로 맵핑
  • 안정적인(비휘발성) 저장매체에 파일을 백업
1.8.2 대용량 저장장치 관리

주 메모리는 모든 데이터와 프로그램을 수용하기에 용량이 너무 작고, 또한 전원이 꺼질 경우 저장하고 있던 데이터가 사라지기 때문에 컴퓨터 시스템은 반드시 주 메모리 내용을 저장하기 위해 보조 저장장치를 제공해야 한다.

1.8.3 캐싱

정보는 통상 어떤 저장장치(주 메모리와 같은)에 보관된다. 정보가 사용됨에 따라 보다 빠른 장치인 캐시에 일시적으로 복사된다. 그러므로 특정 정보가 필요할 경우 먼저 캐시에 그 정보가 있는지를 조사해 보아야 한다. 만약 캐시에 있으면, 그 정보를 캐시로부터 직접 사용하지만, 만일 캐시에 없다면 주 메모리 시스템으로부터 그 정보를 가져와서 사용하며, 이때 이 정보가 다음에 곧 다시 사용될 확률이 높다는 가정 하에 캐시에 넣는다.

다중처리기 환경에서는 어떤 특정 데이터 A의 복사본이 여러 캐시에 존재할 수 있다. 여러 개의 CPU가 모두 동시에 실행될 수 있기에 한 캐시에 있는 A 값이 갱신될 경우 그 값은 A가 존재하는 모든 캐시에 즉각적으로 반영되어야 한다. 이러한 상황을 캐시 일관성 문제라 하며, 이는 일반적으로(운영체제보다 아래 수준에서 처리되는) 하드웨어적 문제이다.

1.8.4 입출력 시스템

운영체제의 목적 중 하나는 사용자에게 특정 하드웨어 장치의 특성을 숨기는 것이다. 이것은 사용자가 일일히 컨트롤하게 하기보다는 운영체제가 제어해주게 한다.

1.9 보호와 보안

컴퓨터 시스템이 여러 프로세스의 병렬 실행을 허용한다면, 데이터에 대한 접근은 반드시 규제되어야 한다. 이를 위해 파일, 메모리 세그먼트, CPU 및 다른 자원들에 대한 운영체제로부터 적절한 허가를 획득한 프로세스만 작업할 수 있도록 보장하는 기법이 필요하다. 메모리 주소 지정 하드웨어는 자신의 주소 영역에서만 실행될 수 있도록 해야한다.

1.10 분산 시스템

분산 시스템은 물리적으로 떨어져 있는 이기종 컴퓨터들의 집합이다. 분산 시스템의 컴퓨터들은 사용자가 시스템 내의 다양한 자원들에 접근할 수 있도록 네트워크로 연결되어 있다.

네트워크는 노드간의 거리에 의해 타입이 결정된다. 로컬 에리어 네트워크(LAN)는 한 방, 한 층, 또는 한 건물에 존재한다. 와이드 에리어 네트워크(WAN)는 통상 건물, 도시 또는 국가 사이를 연결한다.

1.11 전용 시스템

1.11.1 실시간 내장형 시스템

이 장치들은 자동차 엔진, 공장용 로봇, VCR, 전자파 오븐 등 아주 특정한 작업만을 실행하는 경향이 있다. 일반적으로 사용자 인터페이스가 거의 없는 편이다.

1.11.2 멀티미디어 시스템

대부분의 운영체제는 텍스트 파일, 프로그램, 문서 편집기의 문서 및 스프레드시트 등 전통적인 데이터를 처리하도록 설계된다.

1.11.3 휴대용 시스템

이동 전화나 PDA 등을 말한다.

1.12 계산 환경

1.12.1 전통적 계산

네트워크 연결은 더 많은 데이터를 더 값싸게 사용할 수 있게 만든다. 이러한 홈 계산 환경을 보안 침해로부터 보호하기 위해 방화벽(firewall)을 가지고 있다.

오늘날 전통적 시분할 시스템은 흔하지 않다. 동일한 스케줄링 기법이 워크스테이션과 서버에서 사용되고 있다.

1.12.2 클라이언트 서버 계산

PC가 빨라지고, 가격이 낮아짐에 따라 사람들은 중앙식 시스템으로부터 이탈하기 시작했다. 중앙식 시스템에 연결된 터미널은 PC로 대체되고 있다.

서버 시스템은 넓게는 계산 서버와 파일 서버로 구분된다.

  • 계산-서버 시스템 : 클라이언트가 어떤 작업을 요청할 수 있는 인터페이스를 제공한다. 그에 대한 응답으로 서버는 작업을 실행하고 그 결과를 클라이언트에게 돌려보낸다. 데이터베이스를 실행하는 서버가 그런 예이다.
  • 파일-서버 시스템 : 클라이언트가 파일을 생성, 갱신, 읽기 및 제거할수 있는 파일 시스템 인터페이스를 제공한다. 웹브라우저 클라이언트에게 파일을 전달하는 웹 서버가 그런 예이다.
1.12.3 피어 간 계산

이 모델은 클라이언트와 서버가 서로 구별되지 않는다. 각 피어는 누가 서비스를 요청하느냐, 제공하느냐에 따라 클라이언트 및 서버로 동작한다.

1.12.4 웹 기반 컴퓨팅

웹은 다양한 장치를 통한 접근을 허용한다. PC, 워크스테이션, 휴대전화 등.

1.13 오픈소스 운영체제

(밑은 다음에 정리한다.)

1.13.1 역사
1.13.2 Linux
1.13.3 BSD Linux
1.13.4 Solaris
1.13.5 유틸리티

1.14 요약

운영체제는 하드웨어를 관리할 뿐 아니라 응용 프로그램이 실행되기 위한 환경을 제공하는 소프트웨어다.

컴퓨터가 프로그램을 실행하려면 프로그램이 주 메모리에 있어야 한다. 주 메모리는 처리기가 직접 접근할 수 있는 유일한 대량 저장장치다.

주 메모리는 전원이 꺼지거나 중단되면 그 내용을 잃는 휘발성 저장장치다. 그렇기에 보조 저장장치를 제공한다. 보조 저장장치는 대용량의 데이터를 영원히 보존할 수 있는 비휘발성 형태의 저장장치다.

컴퓨터 시스템의 다양한 저장장치는 속도와 비용에 따라 계층 구조로 구성된다. 상위 계층일 수록 비싸지만 속도가 빠르고 계층을 내려올 수록 비트 당 비용은 감소하고 접근 속도는 증가한다.

컴퓨터 시스템을 설계하는 데에는 다양한 전략들이 있다. 단일처리기 시스템은 하나의 처리기만을 가지는 반면 다중처리기 시스템은 둘 이상의 처리기를 갖는다.

가장 일반적인 다중처리기는 대칭형 다중처리기다. 이 다중처리기는 처리기들이 동등하게 취급되며 다른 처리기와는 독립적으로 실행된다. 클러스터형 시스템은 다중처리기의 특별한 형태이며 LAN으로 연결된 다수의 컴퓨터들로 구성된다.

다중 프로그래밍에서는 한 번에 여러 작업들이 메모리에 유지된다. 따라서 CPU는 항상 실행할 작업을 가지게 된다. 시분할 시스템은 다중 프로그래밍의 확장이며 CPU 스케줄링 알고리즘은 작업들을 빠르게 교환해 가며 실행함으로써 마치 각 작업이 동시에 실행되는 것 같은 착각을 유발시킨다.

운영체제는 컴퓨터 시스템의 정확한 동작을 보장해야 한다. 그래서 사용자 모드, 커널 모드 두 가지 모드를 제공한다.

타이머는 무한 루프를 방지한다.

운영체제는 프로세스를 관리하는데 어느 프로세스가 메모리의 어느 영역을 사용하고 있는지를 추적한다. 또한 메모리 공간의 동적 할당 및 반환을 책임진다.

comments powered by Disqus