Notice
Recent Posts
Recent Comments
05-21 07:17
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
Archives
Today
Total
관리 메뉴

Byeol Lo

2.3 System Calls 본문

OS/OS Design

2.3 System Calls

알 수 없는 사용자 2024. 4. 8. 00:26

 System calls는 운영체제에서 제공하는 서비스에 대한 인터페이스를 제공한다. 이러한 호출은 일반적으로 C와 C++로 작성된 함수로 제공되며, 저수준의 작업(하드웨어를 직접 접근하는 작업)은 어셈블리 언어 명령어를 사용하여 작성해야 할 수도 있다.

 

2.3.1 Application Programming Interface

 시스템은 초당 수천 번의 시스템 호출을 수행한다. 그러나 대부분의 프로그래머들은 그걸 실감하진 않는다. 일반적으로 프로그램 개발자들은 API(Application Programming Interface)에 따라 프로그램을 설계한다. API는 프로그래머에게 사용 가능한 함수 세트를 지정하고, 각 함수에 전달되는 매개변수와 프로그래머가 기대할 수 있는 반환 값들을 포함한다. 우리가 가장 많이 사용하는 세 가지 API는 Windows 시스템을 위한 Windows API, POSIX(UNIX, Linux, mac OS) 시스템을 위한 POSIX API, 그리고 Java 가상 머신에서 실행되는 프로그램을 위한 Java API이다. 프로그래머는 운영체제가 제공하는 코드 라이브러리를 통해 API에 접근한다. C 언어로 작성된 UNIX 및 Linux 프로그램의 경우에는 이 라이브러리는 libc라고 불린다. 참고로 특별히 명시되지 않는 한 이 텍스트 전반에 사용된 시스템 호출 이름들은 일반적인 예시다. 각 운영체제는 각 시스템 호출에 대해 자체적인 이름을 가진다.

 API를 구성하는 함수들은 일반적으로 프로그래머를 대신하여 실제 syscall을 호출한다. Windows 함수 CreateProcess()는 실제로 커널에서 NTCreateProcess() syscall을 호출한다. 프로그래머가 실제 syscall을 직접 호출한다기 보다는 이식성에 관련된 이점이다. API를 사용하여 프로그램을 설계하는 응용 프로그램 프로그래머는 자신의 프로그램이 동일한 API를 지원하는 모든 시스템에서 컴파일되고 실행되는 것을 기대할 수 있다. 게다가 실제 시스템 호출은 프로그래머에게 제공되는 API 보다 자세하고 다루기 어려울 수 있다. 그럼에도 불구하고 API 내의 함수와 커널 내의 관련 시스템 호출 사이에는 종종 강한 상관관계가 존재한다. 실제로 POSIX와 Windows API의 많은 부분이 UNIX, Linux, Windows 운영체제에서 제공하는 네이티브 시스템 호출과 유사하다.

 시스템 호출을 처리하는 데 또 다른 중요한 요소는 실행 시간 환경(RTE, run-time environment)이고, RTE란 주어진 프로그래밍 언어로 작성된 애플리케이션을 실행하는 데 필요한 소프트웨어 전체 세트, 컴파일러나 인터프리터 뿐만 아니라 라이브러리와 로더와 같은 다른 소프트웨어를 포함하는 개념이다. RTE는 운영체제에서 제공하는 시스템 호출에 대한 링크 역할을 하는 시스템 호출 인터페이스를 제공한다. 시스템 호출 인터페이스는 API 내의 함수 호출을 가로채서 운영체제 내에서 필요한 시스템 호출을 호출한다. 일반적으로 시스템 호출에는 번호가 연결되어 있으며, 시스템 호출 인터페이스는 이러한 번호에 따라 인덱싱된 테이블을 유지한다. 그런 다음 시스템 호출 인터페이스는 운영 시스템 커널 내에서 의도된 시스템 호출을 호출하고 시스템 호출의 상태를 반환하게 된다.

 caller는 syscall 이 실행중에 무엇을 하거나 어떻게 구현되는지 알 필요가 없다. 오히려 호출자는 API를 준수하고 해당 시스템 호출의 결과로 운영체제가 무엇을 할 것인지만 이해하면 된다. 따라서, 운영체제 인터페이스의 대부분의 세부 사항은 API에 의해 프로그래머로부터 은닉화된다.

 

 시스템 호출(syscall)은 사용 중인 컴퓨터에 따라 다른 방식으로 발생한다. 종종 원하는 시스템 호출의 신원뿐만 아니라 더 많은 정보가 필요하다. 정확한 정보의 종류와 양은 특정 운영체제와 호출에 따라 다르다. 운영체제에 매개변수를 전달하는 세 가지 일반적인 방식이 있는데, 가장 간단한 것은 레지스터에 매개변수를 전달하는 것이다. 하지만, 경우에 따라 매개변수가 일반적으로 메모리의 블록 또는 테이블에 저장되고, 블록의 주소가 레지스터의 매개변수로 전달된다.

 

 리눅스는 이러한 접근 방식을 조합하여 사용하는데, 매개변수가 다섯 개 이하인 경우, 레지스터가 사용된다. 매개변수가 다섯 개를 초과하는 경우에는 블록 방식이 사용된다. 매개변수는 또한 프로그램에 의해 stack에 push 되거나, 운영체제에 의해 stack에서 꺼내질(pop) 수 있다. 일부 운영체제는 매개변수의 수나 길이에 제한이 없기 때문에 블록 또는 스택 방식을 선호한다.

 

2.3.3 Types of System Calls

 시스템 호출은 일반적으로 Process Control, File Management, Device Management, Information Maintenance, Communications, Protection 으로 분류될 수 있다.

  • Process Control
    • Create process, Terminate process
    • Load, Execute
    • Get process attributes, Set process attributes
    • Wait event, Signal event
    • Allocate and free memory
  • File Management
    • Create file, Delete file
    • Open, Close
    • Read, Write, Reposition
    • Get file attributes, Set file attributes
  • Device Management
    • Request device, Release device
    • Read, Write, Reposition
    • Get device attributes, Set device attributes
    • Logically attach or detach Devices
  • Information Management
    • Get time or date, Set time or date
    • Get system data, Set system data
    • Get process, file, or device attributes
    • Set process, file, or device attributes
  • Communications
    • Create, Delete communication connection
    • Send, Receive messages
    • Transfer status information
    • Attach or detach remote devices
  • Protection
    • get file permissions
    • set file permissions

 

2.3.3.1 Process Control

 프로세스는 정상적으로(end()) 중단 또는 비정상적으로(abort()) 중단이 가능해야 한다. 현재 실행 중인 프로그램을 비정상적으로 종료하기 위한 시스템 호출이 이루어지거나, 프로그램이 오류 트랩을 발생시킬 경우에 메모리 덤프가 되고 오류 메시지가 생성된다. 덤프는 디스크 상의 특별한 로그 파일에 기록되며, 프로그래머가 오류나 버그를 찾아 수정하는 데 도움을 주기 위해 설계된 시스템 프로그램인 debugger에 의해 검토될 수 있다. 이를 통해 문제의 원인을 파악할 수 있고, 정상적이거나 비정상적인 상황에서 운영체제는 호출한 command interpreter에 제어를 이전해야 한다. 그러면 command interpreter는 다음 명령을 읽고 처리가 계속된다. 오류에 대응하기 위해 사용자가 적절한 명령을 내릴 것으로 가정하고, GUI 시스템에서는 팝업 창이 사용자에게 오류를 알리고 지침을 요청할 수 있다. 일부 시스템은 오류가 발생한 경우 특별한 복구 조치를 허용할 수 있다.

 프로그램은 오류의 심각도에 따라 다양한 오류 수준을 할당하여, 오류 발생 시 비정상적으로 종료하는 방식을 취할 수 있다. 오류 수준 0은 프로그램이 정상적으로 종료됨을 의미하며, 더 높은 수준의 오류 매개변수는 더 심각한 오류를 나타낸다. 이 오류 수준을 기반으로 다음에 취할 조치가 결정될 수 있다. 낮은 수준의 오류의 경우는 그냥 경고만 표시하고 다음 명령어를 실행하던가 심각한 수준의 오류는 프로그램을 종료하거나 추가적인 조치를 취할 수 있는 것이다.

 사용자는 하나의 프로세스가 실행중인 프로그램이 다른 프로그램을 load()하고 execute()하는 것 또한 할 수 있다. 여기서 load된 프로그램이 종료되었을 때 제어를 어디로 반환할지 의문을 가질 수 있는데, 기존 프로그램이 손실되었는지, 저장되었는지, 새 프로그램과 동시에 실행을 계속할 수 있는지와 관련이 있다.

 하나의 프로그램에서 다른 프로그램을 실행시키고, 그 실행된 프로그램이 종료되었을 때, 원래 실행하던 프로그램으로 돌아갈 수 있도록 원래 프로그램의 상태를 보존해야 한다. 이를 통해 한 프로그램이 다른 프로그램을 호출하는 메커니즘을 실질적으로 구현할 수 있다. 그리고 두 프로그램이 동시에 계속 실행된다면, 다중 프로그래밍 할 수 있는 새로운 프로세스를 생성한 것이다. 이 목적을 위해 특별히 설계된 시스템 호출이 있다(create_process()).

새로운 프로세스를 생성하거나 프로세스 집합을 생성할 경우, 해당 프로세스의 실행을 제어할 수 있어야 한다. 이러한 제어는 프로세스의 속성, 예를 들어 프로세스의 우선순위, 최대 허용 실행 시간 등을 결정하고 재설정할 수 있는 능력을 필요로 한다(get_process_attributes()set_process_attributes()). 또한, 생성한 프로세스가 잘못되었거나 더 이상 필요하지 않은 경우 해당 프로세스를 종료할 수도 있다(terminate_process()).

 새로운 프로세스를 생성한 후, 우리는 그들이 실행을 마칠 때까지 기다릴 필요가 있을 수 있다. 일정 시간이 지나기를 기다릴 수도 있고(wait_time()), 특정 이벤트가 발생하기를 기다리게 될 수도 있다(wait_event()). 그런 다음 프로세스는 해당 이벤트가 발생했다는 신호를 보내야 한다(signal_event()).

 또한 두 개 이상의 프로세스가 데이터를 공유하는 경우가 자주 있다. 공유되는 데이터의 무결성을 보장하기 위해, 운영 시스템은 프로세스가 공유 데이터에 대한 잠금을 설정할 수 있는 시스템 호출을 제공한다. 그러면 잠금이 해제될 때까지 다른 프로세스는 해당 데이터에 접근할 수 없게 된다. 이러한 시스템 호출에는 일반적으로 acquire_lock()release_lock()이  포함된다.

  • 프로세스는 정상적으로 종료 end(), 비정상적으로 종료 abort() 할 수 있다.
  • 오류, 트랩이 발생했을 경우 메모리 덤프가 발생되고 오류 메시지가 생성된다.
  • 덤프가 발생했을때 디버거를 사용하여 트러블 슈팅을 한다.
  • 낮은 수준의 오류의 경우는 경고 표시, 심각한 수준의 오류는 프로그램을 종료하거나 추가적인 조치를 취할 수 있다.
  • 프로세스는 다른 프로그램을 load 및 execute할 수 있다
  • 새 프로세스가 종료될 때 제어가 기존 프로그램으로 반환되면, 기존 프로그램의 메모리 이미지를 저장한다.
  • 다중 프로세싱을 위해 create_process로 새로운 프로세스를 생성하고, 다중 프로그래밍을 할 수 있다.
  • 새로운 프로세스 및 프로세스 집합을 제어하기 위해 get_process_attributes, set_process_attributes() 가 있다.
  • 프로세스를 종료하기 위해 terminate_process()로 종료시킬 수도 있다.
  • 프로세스가 기다리게 하기 위해 wait_time, wait_event 등으로 기다리게 할 수 있다.
  • 프로세스가 이벤트가 발생했다는 신호를 signal_event로 보낼 수 있다.
  • 프로세스가 데이터를 공유할 때, acquire_lock과 release_lock을 통해 잠금을 얻을 수 있고, 다시 반환할 수도 있다.

 프로세스 제어에는 여러 측면과 변형이 있어, 이 개념을 명확히 하기 위해 단일 작업 시스템과 멀티태스킹 시스템을 다루는 두 가지 예를 들어 설명하겠다. 아두이노는 마이크로컨트롤러와 다양한 이벤트에 반응하는 입력 센서(예: 빛, 온도, 기압 변화 등)로 구성된 간단한 하드웨어 플랫폼이다. 아두이노용 프로그램을 작성하기 위해, 우리는 먼저 PC에서 프로그램을 작성한 다음 컴파일된 프로그램(sketch라고 함)을 USB 연결을 통해 PC에서 아두이노의 플래시 메모리로 업로드한다. 표준 아두이노 플랫폼은 운영 시스템을 제공하지 않는다. 대신, 부트 로더라고 하는 작은 소프트웨어가 스케치를 아두이노 메모리의 특정 영역에 로드한다. 스케치가 로드되면, 프로그램된 이벤트에 반응하기 위해 실행을 시작한다. 예를 들어, 아두이노의 온도 센서가 온도가 특정 임계값을 초과했다고 감지하면, 스케치는 팬의 모터를 시작하도록 할 수 있다. 아두이노는 한 번의 메모리에 하나의 스케치만 존재할 수 있기 때문에 단일 작업 시스템으로 간주된다. 다른 스케치가 로드되면 기존의 스케치를 대체한다. 또한, 아두이노는 하드웨어 입력 센서를 넘어서는 사용자 인터페이스를 제공하지 않는다.

 FreeBSD는 멀티태스킹 시스템의 한 예로, 사용자가 시스템에 로그인하면 선택한 셸이 실행되어 사용자의 명령을 기다리고 요청받은 프로그램을 실행한다. 멀티태스킹 시스템인 FreeBSD에서는 다른 프로그램이 실행되는 동안에도 명령 해석기가 계속 실행될 수 있다. 새로운 프로세스를 시작하기 위해 셸은 fork() 시스템 호출을 실행하고, 선택된 프로그램은 exec() 시스템 호출을 통해 메모리에 로드되어 실행된다. 명령에 따라 셸은 프로세스가 끝날 때까지 기다리거나, 프로세스를 "백그라운드에서" 실행한다. 백그라운드에서 실행되는 프로세스는 키보드로부터 직접 입력을 받을 수 없으므로, I/O는 파일이나 GUI 인터페이스를 통해 이루어진다.

 사용자는 다른 프로그램의 실행을 요청하거나, 실행 중인 프로세스의 진행 상황을 모니터링하거나, 그 프로그램의 우선순위를 변경하는 등의 작업을 할 수 있다. 해당 프로세스가 완료되면, exit() 시스템 호출을 실행하여 종료하고, 0 또는 0이 아닌 에러 코드를 반환합니다. 이 상태나 에러 코드는 셸이나 다른 프로그램에서 사용할 수 있다.

  • FreeBSD에서 fork로 새 프로세스를 실행할 수 있다.
  • 선택된 프로그램을 exec을 통해 메모리에 로드하고 실행할 수 있다.
  • exit을 통해 프로세스를 종료할 수 있다.

 

2.3.3.2 File Management

 여기서는 파일 시스템과 관련된 일반적인 시스템 호출을 논의한다. 먼저, 파일을 생성(create())하고 삭제(delete())할 수 있는 기능이 필요하다. 이러한 시스템 호출은 파일의 이름과 파일의 일부 속성이 필요할 수 있다. 파일을 생성한 후에는 파일을 열어(open()) 사용해야 한다. 또한, 파일을 읽기(read()), 쓰기(write()), 위치를 재조정(reposition())하는 작업(예: 파일의 시작으로 되감기나 파일의 끝으로 이동)도 필요할 수 있다. 마지막으로, 파일을 닫아(close()) 더 이상 사용하지 않음을 나타내야 한다.

 파일 시스템에서 파일을 조직하기 위한 디렉토리 구조가 있다면, 디렉토리에 대해서도 위의 파일 조작과 같은 세트의 작업이 필요할 수 있을 것이다. 또한, 파일이나 디렉토리에 대해 다양한 속성의 값을 결정하고 필요한 경우 이러한 값을 설정할 수 있어야 한다. 파일 속성에는 파일 이름, 파일 유형, 보호 코드, 회계 정보 등이 포함된다. 이 기능을 위해 최소한 두 가지 시스템 호출, 즉 파일 속성 가져오기(get_file_attributes())와 파일 속성 설정하기(set_file_attributes())가 필요하다. 일부 운영 체제는 파일 이동(move()) 및 복사(copy())와 같은 더 많은 호출을 제공할 수 있으며, 다른 운영 체제는 코드와 다른 시스템 호출을 사용하여 이러한 작업을 수행하는 API를 제공할 수 있다. 또한, 시스템 프로그램을 제공하여 이러한 작업을 수행할 수 있으며, 다른 프로그램에서 호출할 수 있는 시스템 프로그램이 있다면, 각각이 다른 시스템 프로그램에 의해 API로 간주될 수 있다.

  • create를 통해 파일을 생성하고
  • delete를 통해 파일을 삭제한다.
  • open을 통해 파일을 연 후에
  • read를 통해 파일을 읽고,
  • reposition으로 파일 내의 특정 위치로 이동하고,
  • write를 통해 파일을 쓴 후에
  • close를 통해 파일을 닫는다.
  • get_file_attributes와 set_file_attributes로 파일 속성들을 접근할 수 있다.
  • 일부 운영체제에서는 move, copy로 다양한 접근을 제공한다.

 

2.3.3.3 Device Management

 프로세스는 실행을 위해 여러 리소스가 필요할 수 있다(주 메모리, 디스크 드라이브, 파일 접근 등). 리소스가 사용 가능하면, 이들을 할당받고 사용자 프로세스에 (장치의) 제어권이 반환된다. 만약 그렇지 않다면, 충분한 리소스가 사용 가능해질 때까지 프로세스는 대기해야 한다. 운영 시스템에 의해 제어되는 다양한 리소스는 장치로 생각할 수 있고, 이러한 장치 중 일부는 물리적 장치(예: 디스크 드라이브)이고, 다른 일부는 추상적이거나 가상의 장치(예: 파일)로 생각할 수 있다.

 여러 사용자를 지원하는 시스템에서는 우선 장치를 요청(request())해야 하며, 이를 통해 해당 장치의 독점 사용을 보장받는다. 장치 사용을 마친 후에는 이를 해제(release())하게 된다. 이 기능은 파일에 대한 open()close() 시스템 호출과 유사하다. 다른 운영 시스템은 장치에 대한 관리되지 않은 접근을 허용한다. 이 경우 장치 경합 및 가능한 교착 상태의 위험이 있고, 이는 후에 다룬다.

 장치가 요청되어(그리고 우리에게 할당된 후) 우리는 파일과 마찬가지로 장치를 읽기(read()), 쓰기(write()), (가능하다면) 위치를 재조정(reposition())할 수 있다. 실제로, 입출력 장치와 파일 사이의 유사성은 UNIX를 포함한 많은 운영 시스템에서 이 둘을 결합한 file-device 구조로 통합할 정도로 크다. 이 경우, 파일과 장치 모두에 대해 일련의 시스템 호출이 사용된다. 때때로, 입출력 장치는 특별한 파일 이름, 디렉토리 위치, 또는 파일 속성으로 식별된다. 사용자 인터페이스 역시 기본적인 시스템 호출이 다르더라도 파일과 장치가 유사하게 보이도록 할 수 있다. 이 말은 둘 입출력 장치와 파일은 기본적으로 다르게 작동하지만, 운영 시스템 디자인에서는 이 둘 사이의 구분을 사용자에게 명확하게 드러내지 않는다는 것이다(파일을 드래그 앤 드롭이 그 예). 이러한 설계의 결정은 사용자에게 더 직관적인 인터페이스를 제공하기 위해 만들어진 것이다.

  • request로 장치 요청을 할 때, 제어권을 얻을 수 있다.
  • release로 장치 제어권을 반환한다.

 

2.3.3.4 Information Maintenance

 많은 시스템 호출들은 사용자 프로그램과 운영 체제 간 정보를 전달하는 목적으로 존재한다. 예를 들어, 대부분의 시스템에는 현재 시간(time())과 날짜(date())를 반환하는 시스템 호출이 있다. 다른 시스템 호출들은 운영 체제의 버전 번호, 남은 메모리나 디스크 공간 등 시스템에 대한 정보를 반환할 수 있다.

 또한, 프로그램 디버깅에 도움이 되는 시스템 호출들도 있다. 많은 시스템들은 메모리 덤프(dump())의 시스템 호출을 제공하며, 이는 디버깅에 유용하다. Linux 시스템에서 사용할 수 있는 프로그램인 strace는 실행되는 각 시스템 호출을 나열한다. 심지어 마이크로프로세서는 CPU가 모든 명령 후에 트랩을 실행하는 단일 스텝(single step)이라고 알려진 CPU 모드를 제공한다. 이 트랩은 보통 디버거에 의해 포착된다.

 많은 운영 체제는 프로그램의 time profile을 제공하여 특정 위치나 위치 집합에서 프로그램이 실행되는 시간을 나타낸다. time profile은 추적 기능이나 정기적인 timer interrupt를 필요로 한다. 타이머 인터럽트가 발생할 때마다 프로그램 카운터의 값이 기록된다. 자주 발생하는 타이머 인터럽트를 통해 프로그램의 다양한 부분에서 소비된 시간에 대한 통계적 그림을 얻을 수 있다.

 또한, 운영 체제는 모든 프로세스에 대한 정보를 유지하고, 이 정보에 접근하기 위해 시스템 호출이 사용된다. 일반적으로, 프로세스 정보를 얻고 설정하기 위해 호출이 사용된다(get_process_attributes()set_process_attributes()).

  • 운영 체제의 정보들을 Information Maintenance 관련 시스템 호출을 사용한다.
  • 현재시간은 time 을 통해 알수 있고, 날짜는 date를 통해 알 수 있다.
  • dump는 프로그램 디버깅에 도움을 준다.
  • 트랩을 실행할 때 single step의 CPU 모드로 들어간다.
  • 프로그램의 time profile을 통해 실행되는 시간을 알 수 있다.
  • time profile은 정기적인 timer interrupt를 필요로 한다.
  • timer interrupt가 발생할 때마다 Program Counter의 값이 기록된다.
  • get_process_attributes를 통해 프로세스의 정보를 얻을 수 있다.
  • set_process_attributes를 통해 프로세스의 정보를 설정할 수 있다.

 

2.3.3.5 Communication

 프로세스 간 통신에는 Message-passing modelShared-memory model이라는 두 가지 일반적인 모델이 있다. Message-passing Model 에서는 통신하는 프로세스들이 정보를 전달하기 위해 서로 메시지를 교환한다. 메시지는 직접적으로 또는 공통 메일박스를 통해 간접적으로 프로세스 간에 교환될 수 있다. 통신을 시작하기 전에 연결이 열려야 하고, 다른 통신자의 이름도 알아야 하는데, 이는 동일한 시스템의 다른 프로세스일 수도 있고 통신 네트워크로 연결된 다른 컴퓨터의 프로세스일 수도 있다.

 네트워크의 각 컴퓨터는 일반적으로 알려진 host name을 가지고 있고, 호스트는 또한 IP 주소와 같은 네트워크 식별자를 가지고 있다. 마찬가지로 각 프로세스는 process name을 가지고 있으며, 이 이름은 운영 체제가 프로세스를 참조할 수 있는 식별자로 변환된다. get_hostid() 및 get_processid() 시스템 호출이 이러한 변환을 수행한다. 그런 다음 식별자들은 시스템의 통신 모델에 따라 파일 시스템에 의해 제공되는 일반적인 open() 및 close() 호출이나 특정 open_connection() 및 close_connection() 시스템 호출에 전달된다.

 수신 프로세스는 보통 accept_connection() 호출을 통해 통신이 이루어질 수 있도록 허가를 해야 한다. 연결을 받을 대부분의 프로세스는 그 목적을 위해 제공되는 특수 목적의 daemon이다. 이들은 wait_for_connection() 호출을 실행하고 연결이 이루어지면 깨어난다. 클라이언트와 수신 daemon인 serverread_message() 및 write_message() 시스템 호출을 사용하여 메시지를 교환하고, close_connection() 호출로 통신을 종료한다.

 Shared-memory Model 에서, 프로세스는 공유 메모리 생성(shared_memory_create()) 및 공유 메모리 첨부(shared_memory_attach()) 시스템 호출을 사용하여 다른 프로세스가 소유한 메모리 영역을 생성하고 접근한다. 일반적으로, 운영 체제는 한 프로세스가 다른 프로세스의 메모리에 접근하는 것을 방지하려고 시도한다. 공유 메모리는 두 개 이상의 프로세스가 이러한 제한을 제거하기로 동의해야 한다. 그 후, 공유 영역에서 데이터를 읽고 쓰면서 정보를 교환할 수 있다. 데이터의 형태는 프로세스에 의해 결정되며 운영 체제의 제어를 받지 않는다. 프로세스는 또한 동시에 같은 위치에 쓰지 않도록 보장하는 책임이 있다.

 방금 논의한 두 모델은 운영 체제에서 흔하며, 대부분의 시스템은 두 가지를 모두 구현한다. Message-passing model은 충돌을 피할 필요가 없기 때문에 작은 양의 데이터를 교환하는 데 유용하다. 또한, 이 모델은 컴퓨터 간 통신에 Shared-memory model보다 구현하기가 더 쉽다. Shared-memory Model는 컴퓨터 내에서 이루어질 때 메모리 전송 속도로 통신할 수 있기 때문에 최대 속도와 편의성을 제공한다. 그러나, 공유 메모리를 공유하는 프로세스 간의 보안와 동기화 영역에서 문제가 존재하게 된다.

  • 프로세스 간의 통신에는 Message-passing model과 Shared-memory model이 있다.
  • Message-passing model 에서는 프로세스 간의 메시지 교환 방식을 말한다.
  • Shared-memory model 에서는 공유 메모리를 생성하여 프로세스간에 메모리 전송 속도로 통신을 할 수 있다.
  • get_hostid를 통해 host의 식별자로 여길 수 있고,
  • get_processid를 통해 process의 식별자로 여길 수 있다.
  • 이런 식별자들은 open, close 또는 open_connection, close_connetion을 통해 시스템 호출로 전달됨
  • 수신 프로세스에서는 accept_connection을 통해 통신이 이루어질 수 있도록 허가한다.
  • 이러한 연결을 받을 대부분의 프로세스는 그 목적을 위해 제공되는 특수 목적의 daemon이다.
  • daemon은 wait_for_connection을 실행하고 있는 상태에 있으며, 수신이 오면 깨어난다.
  • 수신 daemon인 서버는 read_message, write_message 을 사용하여 메시지를 교환한다.
  • close_connection으로 통신을 종료한다.
  • 프로세스는 shared_memory_create로 공유 메모리를 생성한다.
  • 프로세스는 shared_memory_attach로 공유 메모리에 접근한다.
  • shared-memory model이 훨씬 빠르지만 보안과 동기화 영역에서 문제가 존재한다.

 

2.3.3.6 Protection

 보호는 컴퓨터 시스템이 제공하는 자원에 대한 접근을 제어하는 메커니즘을 제공한다. 이전에는 보호는 여러 사용자가 있는 다중 프로그램 컴퓨터 시스템에서만 고려되었지만, 네트워킹과 인터넷의 등장으로, 서버부터 모바일 휴대 장치 등 거의 모든 컴퓨터 시스템은 보호 문제를 고려해야 한다.

 일반적으로, 보호를 제공하는 시스템 호출에는 파일과 디스크와 같은 자원의 권한 설정을 조작하는 set_permission()과 get_permission()이 포함된다. allow_user() 및 deny_user() 시스템 호출은 특정 사용자가 특정 자원에 접근할 수 있거나 접근할 수 없도록 지정한다.

  • set_permission 시스템 호출을 통해 파일과 디스크와 같은 자원의 권한을 설정하고,
  • get_permission 시스템 호출을 통해 파일과 디스크와 같은 자원의 권한 정보를 불러온다.
  • allow_user 을 통해 특정 사용자가 특정 자원에 접근할 수 있도록 하고,
  • deny_user 을 통해 특정 사용자가 특정 자원에 접근할 수 없도록 한다.

'OS > OS Design' 카테고리의 다른 글

2.5 Linkers and Loaders  (0) 2024.04.08
2.4 System Services  (0) 2024.04.08
2.2 User and Operating-System Interface  (0) 2024.04.07
2.1 Operating-System Services  (0) 2024.04.07
1.9 Kernel Data Structures  (0) 2024.04.06
Comments