2020. 11. 25. 18:21ㆍ개인공부/운영체제 공룡책 10판
Chapter 3. 프로세스
- 프로세스 개념
- 프로세스 스케줄링
- 프로세스에 대한 연산
- 프로세스 간 통신
- 공유 메모리 시스템에서의 프로세스 간 통신
- 메시지 전달 시스템에서의 프로세스 간 통신
- IPC 시스템의 사례
- 클라이언트 서버 환경에서 통신
- 요약
Chapter 3. 프로세스
프로세스란 실행 중인 프로그램을 말한다. 프로세스는 현대의 컴퓨팅 시스템에서 작업의 단위이다.
3.1 프로세스 개념 -p118
3.1.1 프로세스 -p118
프로세스의 현재 활동의 상태는 프로그램 카운터 값과 프로세서 레지스터의 내용으로 나타낸다.
- 텍스트 섹션 - 실행코드
- 데이터 섹션 - 전역 변수
- 힙 섹션 - 프로그램 실행 중에 동적으로 할당되는 메모리
- 스택 섹션 - 함수를 호출할 때 임시 데이터 저장장소 ( 예: 함수 매개변수, 복귀 주소 및 지역 변수)
텍스트 및 데이터 섹션 크기는 고정되기 때문에 프로그램 실행 시간 동안 크기가 변하지 않는다
스택 및 힙 센셕은 프로그램 실행 중에 동적으로 줄어들거나 커질 수 있다.
함수가 호출될 때마다 함수 매개변수, 지역 변수 및 복귀 주소를 포함하는 활성화 레코드가 스택에 푸시 된다.
3.1 프로세스 상태 process state - p121
프로세스는 실행되면서 그 상태가 변한다. 프로세스의 상태는 현재의 활동에 따라 정의된다.
- new - 프로세스가 생성중이다.
- running - 명령어들이 실행되고 있다.
- waiting - 프로세스가 어떤 이벤트 ( 입출력 완료 또는 신호의 수신같은)가 일어나기를 기다린다.
- ready - 프로세스가 처리기에 할당되기를 기다린다.
- terminated - 프로세스의 실행이 종료되었다.
3.1.3 프로세스 제어 블록 Process Control Block -p121
각 프로세스는 운영체제에서 프로세스 제어 블록 (process control block, PCB)에 의해 표현된다.
PCB는 특정 프로세스와 연관된 여러 정보를 수록하며, 다음과 같은 것들을 포함한다.
1. 프로세스 상태 : 상태는 new, ready, running, waiting, halted(정지) 등이다.
2. 프로그램 카운터 : 프로그램 카운터는 이 프로세스가 다음에 실행할 명령어의 주소를 가리킨다.
3. CPU 레지스터들: 컴퓨터의 구조에 따라 다양한 수와 유형을 가진다. 레지스터에는 누산기, 인덱스 레지스터, 스택 레지스터 범용 레지스터들과 상태코드 정보가 포함된다. 프로그램 카운터와 함께 이 상태 정보는, 나중에 프로세스가 다시 스케줄 될 때 계속 올바르게 실행되도록 하기 위해서 인터럽트 발생 시 저장되어야 한다.
4. CPU-스케줄링 정보: 프로세스 우선순위, 스케줄 큐에 대한 포인터와 다른 스케줄 매개변수를 포함
5. 메모리 관리 정보: 운영체제에 의해 사용되는 메모리 시스템에 따라 기준(base) 레지스터와 한계(limit) 레지스터의 값, 운영체제가 사용하는 메모리 시스템에 따라 페이지 테이블 또는 세그먼트 테이블 등과 같은 정보를 포함한다
6. 회계 정보 : CPU 사용 시간과 경과된 실시간, 시간 제한, 계정 번호, 잡 또는 프로세스 번호 등을 포함한다.
7. 입출력 상태 정보: 이 정보는 이 프로세스에 할당된 입출력 장치들과 열린 파일의 목록 등을 포함한다.
요약하면 프로세스 제어 블록은 약간의 회계 데이터와 함께 프로세스를 시작시키거나 다시 시작시키는데 필요한 모든 데이터를 위한 저장소의 역할을 한다.
3.1.4 스레드 -p122
이제까지 논의한 프로세스 모델은 프로세스가 단일의 실행 스레드를 실행하는 프로그램임을 암시했다.
다중 처리기 시스템에서는 여러 스레드가 병렬로 실행될 수 있다. 스레드를 지원하는 시스템에서는 PCB가 각 스레드에 관한 정보를 포함하도록 확장된다.
3.2 프로세스 스케줄링 Process Scheduling - p123
프로세스 스케줄러는 코어에서 실행 가능한 여러 프로세스 중에서 하나의 프로세스를 선택한다.
단일 CPU 코어 -> 한 번에 2개 이상의 프로세스가 실행될 수 없다.
다중 코어 시스템 -> 한번에 여러개의 프로세스를 실행 가능.
코어보다 많은 프로세스가 있는 경우 초과 프로세스는 코어가 사용 가능해지고 다시 스케줄 될 때 까지 기다려야함.
현재 메모리에 있는 프로세스 수를 다중 프로그래밍 정도 라고 한다.
3.2.1 스케줄링 큐 Scheduling Queue - p123
프로세스가 시스템에 들어가면 준비 큐에 들어가서 준비 상태가 되어 CPU 코어에서 실행되기를 기다린다. 이 큐는 일반적으로 연결 리스트로 저장된다.
준비큐 헤더에는 리스트의 첫 번째 PCB에 대한 포인터가 저장된다
각 PCB에는 준비 큐의 다음 PCB를 가리키는 포인터 필드가 포함된다.
I/O 완료와 같은 특정 이벤트가 발생하기를 기다리는 프로세스는 대기 큐(wait queue)에 삽입된다.
새 프로세스는 처음에 준비 큐에 놓인다. 프로세스는 실행을 위해 선택되거나 또는 디스패치 될 때까지 기다린다. 프로세스에 CPU 코어가 할당되고 실행 상태가 되면, 여러 이벤트 중 하나가 발생할 수 있다.
- 프로세스가 I/O 요청을 공표한 다음 I/O 대기 큐에 놓일 수 있다.
- 프로세스는 새 자식 프로세스를 만든 다음, 자식의 종료를 기다리는 동안 대기 큐에 놓일 수 있다.
- 인터럽트 또는 타임 슬라이스가 만료되어 프로세스가 코어에서 강제로 제거되어 준비 큐로 돌아갈 수 있다.
처음 두 경우에는 프로세스가 결국 대기 상태에서 준비 상태로 전환된 다음 준비 큐에 다시 들어간다.
프로세스는 종료될 때 까지 이 주기를 계속한다. 종료 시점에 모든 큐에서 제거되고 PCB 및 자원이 반환된다.
3.3.2 CPU 스케줄링 p-126
CPU 스케줄러의 역할은 준비 큐에 있는 프로세스 중에서 선택된 하나의 프로세스에 CPU 코어를 할당하는 것이다.
프로세스는 수명주기 동안 준비 큐와 다양한 대기 큐를 이주한다.
3.2.3 문맥교환 Context Switch -p126
CPU 코어를 다른 프로세스로 교환하려면 이전의 프로세스의 상태를 보관하고 새로운 프로세스의 보관된 상태를 복구하는 작업이 필요하다. 이 작업은 문맥 교환 ( context switch )이라고 한다. 문맥은 프로세스의 PCB에 표현된다.
문맥 교환이 일어나면 커널은 과거 프로세스의 문맥을 PCB에 저장하고, 실행이 스케줄된 새로운 프로세스의 저장된 문맥을 복구한다. 문맥 교환 시간은 하드웨어의 지원에 크게 좌우된다.
3.3 프로세스에 대한 연산 Operation on Processes -p128
대부분 시스템 내의 프로세스들은 병행 실행될 수 있으며, 반드시 동적으로 생성되고, 제거 되어야 한다.
3.3.1 프로세스 생성 -p129
실행되는 동안 프로세스는 여러 개의 새로운 프로세스들을 생성할 수 있다. 앞에서 언급한 것과 같이 생성하는 프로세스를 부모 프로세스라고 부르고, 새로운 프로세스는 자식 프로세스라고 부른다. 이 새로운 프로세스들은 각각 다시 다른 프로세스들을 생성할 수 있으며, 그 결과 프로세스의 트리를 형성한다.
일반적으로 프로세스가 자식 프로세스를 생성할 때, 그 자식 프로세스는 자신의 임무를 달성하기 위하여 어떤 자원 ( CPU 시간, 메모리, 파일, 입출력 장치) 이 필요하다. 자식 프로세스는 자원을 운영체제로 부터 직접 얻거나, 부모 프로세스가 가진 자원의 일부분만을 사용하도록 자식 프로세스가 쓸 수 있게 제한하며, 자식 프로세스들을 많이 생성하여 시스템을 과부하 상태로 만드는 프로세스를 방지할 수 있다.
프로세스가 새로운 프로세스를 생성 할 때, 두 프로세스를 실행시키는 데 두 가지 가능한 방법이 존재한다.
1. 부모는 자식과 병행하게 실행을 계속한다.
2. 부모는 일부 또는 모든 자식이 실행을 종료할 때까지 기다린다.
새로운 프로세스들의 주소 공간 측면에서 볼 때 다음과 같은 두 가지 가능성이 있다.
1. 자식 프로세스는 부모 프로세스의 복사본이다( 자식 프로세스는 부모와 똑같은 프로그램과 데이터르 가진다)
2. 자식 프로세스가 자신에게 적재될 새로운 프로그램을 가지고 있다.
3.3.2 프로세스 종료 -p134
프로세스가 마지막 문장의 실행을 끝내고, exit 시스템 콜을 사용하여 운영체제에 자신의 삭제를 요청하면 종료한다. 이 시점에서, 프로세스는 자신을 기다리고 있는 부모 프로세스에 (wait 시스템 콜)을 통해 상태 값(통상 정수값)을 반환할 수 있다. 물리 메모리와 가상 메모리, 열린 파일, 입출력 버퍼를 포함한 프로세스의 모든 자원이 할당 해제되고 운영체제로 반납된다.
부모는 다음과 같이 여러 가지 이유로 인하여 자식 중 하나의 실행을 종료할 수 있다.
- 자식이 자신에게 할당된 자원을 초과하여 사용할 때. 이때는 부모가 자식들의 상태를 검사할 수 있는 방편이 주어져야 한다.
- 자식에게 할당된 태스크가 더 이상 필요 없을 때
- 부모가 exit를 하는데, 운영체제는 부모가 exit 한 후에 자식이 실행을 계속하는 것을 허용하지 않는 경우
몇몇 시스템에서는 부모 프로세스가 종료한 이후에 자식 프로세스가 존재할 수 없다. 그러한 시스템에서는 프로세스가 종료되면 그로부터 모든 자식 프로세스들도 종료되어야 한다. 이것을 연쇄식 종료(cascading termination)이라고 부르며 이 작업은 운영체제가 시행한다.
부모 프로세스는 wait() 시스템 콜을 사용해서 자식 프로세스가 종료할 때를 기다릴 수 있다. wait() 시스템 콜은 부모가 자식의 종료 상태를 얻어낼 수 있도록 하나의 인자를 전달받는다.
종료되었지만 부모 프로세스가 아직 wait() 호울을 하지 않은 프로세스를 좀비(zombie) 프로세스라고 한다.
부모가 wiat()를 호출하면 좀비 프로세스의 프로세스 식별자와 프로세스 테이블의 해당 항목이 운영체제에 반환된다.
부모 프로세스가 wait()를 호출하는 대신 종료하면 자식 프로세스는 고아(orphan) 프로세스가 된다.
Unix에서는 새로운 부모 프로세스로 init프로세스를 지정함으로써 이 문제를 해결한다. init 프로세스는 주기적으로 wait()를 호출 하여 고아 프로세스의 종료 상태를 수집하고 프로세스 식별자와 프로세스 테이블 항목을 반환한다.
Linux는 systemd 이외의 프로세스가 고아 프로세스를 상속하고 종료를 관리하도록 허용한다.
3.3.2.1 Android 프로세스 계층 -p136
Android는 임의의 프로세스를 종료하지 않고 프로세스의 중요도 계층을 식별했으며, 시스템이 프로세스를 종료하여 새로운 또는 보다 중요한 프로세스를 위한 자원을 확보해야 할 경우 중요도가 낮은 프로세스부터 종료한다.
1. 전경 프로세스 ( forground process ) - 사용자가 현재 상호 작용하고 있는 응용 프로그램을 나타내며, 화면에 보이는 현재 프로세스
2. 가시적 프로세스 ( visible process ) - 전경에서 직접 볼 수 없지만 전경 프로세스가 참조하는 활동 ( 즉, 현재 상태가 전경 프로세스에 표시되는 활동을 수행하는 프로세스)을 수행하는 프로세스
3. 서비스 프로세스 ( service process ) - 백그라운드 프로세스와 유사하지만 사용자가 인지할 수 있는 활동 ( 예: 음악 스트리밍)을 수행하는 프로세스
4. 백그라운드 프로세스 (background process) - 활동을 수행하고 있지만 사용자가 인식하지 못하는 프로세스
5. 빈 프로세스 ( empty process ) - 응용 프로그램과 관련된 활성 구성요소가 없는 프로세스
3.4 프로세스 간 통신 -p137
프로세스가 시스템에서 실행 중인 다른 프로세스들에 영향을 주거나 받는다면 이는 협력적 프로세스들이다. 독립적 프로세스는 그 반대다.
프로세스 협력을 허용하는 환경을 제공 하는 이유
1. 정보 공유 ( information sharing) :
여러 응용 프로그램이 동일한 정보( ex: 복사, 붙여넣기) 에 필요를 느낄 수 있으므로, 그러한 정보를 병행적으로 접근할 수 있는 환경을 제공해야 한다.
2. 계산 가속화 ( computation speedup) :
만일 우리가 특정 태스크를 빨리 실행하고자 한다면, 우리는 그것을 서브태스크로 나누어 이들 각각이 다른 서브태스크들과 병렬로 실행되게 해야 한다. 이러한 가속화는 복수 개의 처리 코어를 가진 경우에만 달성할 수 있음에 유의해야 한다.
3.모듈성 ( modularity):
시스템 기능을 별도의 프로세스들 또는 스레드들로 나누어, 모듈식 형태로 시스템을 구성하기를 원할수 있다.
협력적 프로세스들은 데이터를 교환할 수 있는, 즉 서로 데이터를 보내거나 받을 수 있는 프로세스 간 통신 ( interprocess communication, IPC ) 기법이 필요하다. 프로세스 간 통신에는 기본적으로 공유 메모리 ( shared memory) 와 메시지 전달 ( message passing) 두가지 모델이 있다.
메시지 전달 모델 :
적은 양의 데이터를 교환하는데 유용하다. 분산시스템에서 공유메모리보다 구현하기 쉽다.
통상 시스템 콜을 사용하여 구현되므로 커널 간섭 등의 부가적인 시간 소비 작업이 필요하기 때문에 공유 메모리 모델이 메시지 전달보다 빠르다.
공유 메모리 시스템:
공유 메모리 영역을 구축할 때만 시스템 콜이 필요하다. 그래서 구축이 되면 모든 접근은 일반적인 메모리 접근으로 취급되어 커널의 도움이 필요없다.
3.5 공유 메모리 시스템에서의 프로세스 간 통신 -p137
공유 메모리를 사용하는 프로세스 간 통신에는 통신하는 프로세스들이 공유 메모리 영역을 구축해야 한다.
생산자 -소비자 관점 :
생산자 프로세스: 정보를 생산
소비자 프로세스 : 정보를 소비
ex)
컴파일러는 어셈블리 코드 생산, 어셈블러는 이것을 소비.
어셈블러는 목적 모듈 생산, 로더는 이들을 소비.
웹서버는 HTML 파일과 이미지와 같은 웹 콘텐츠를 생산, 웹브라우저가 이런 자원을 요청하고 소비함.
생산자 -소비자 문제의 하나의 해결책은 공유 메모리 사용.!
생산자가 정보를 채워넣고 소비자가 소모할 수 있는 항목들의 버퍼가 반드시 사용 가능해야 함.
버퍼에는 2가지 유형이 있다.
1. 무한 버퍼 ( unbounded buffer) : 생산자 소비자 문제에서는 버퍼의 크기에 실질적인 한계가 없다. 소비자는 새로운 항목을 기다려야만 할 수도 있지만, 생산자는 항상 새로운 항목을 생산할 수 있다.
2. 유한 버퍼 ( bounded buffer ) : 버퍼의 크기가 고정되어 있다고 가정한다. 이 경우 버퍼가 비어있으면 소비자는 반드시 대기해야 하며, 모든 버퍼가 채워져 있으면 생산자가 대기해야 한다.
3.6 메시지 전달 시스템에서의 프로세스 간 통신 -p141
메시지 전달 방식은 동일한 주소 공간을 공유하지 않고도 프로세스들이 통신을 하고, 그들의 동작을 동기화할 수 있도록 허용하는 기법을 제공한다. 프로세스들이 네트워크에 의해 연결된 다른 컴퓨터들에 존재할 수 있는 분산환경에서 특히 유용하다.
하나의 링크와 send() / receive() 연산을 논리적으로 구현 하는 다수의 방법
- 직접 또는 간접 통신
- 동기식 또는 비동기식 통신
- 자동 또는 명시적 버퍼링
3.6.1 명명 -p142
직접 통신하에서, 통신을 원하는 각 프로세스는 토인의 수신자 또는 송신자의 이름을 명시해야 한다.
- send( P, message ) - 프로세스 P에 메시지를 전송한다
- receive( Q, message ) - 프로세스 Q로부터 메시지를 수신한다.
이 기법에서 통신 연결은 다음의 특성을 가진다
- 통신을 원하는 각 프로세스의 쌍들 사이에 연결이 자동으로 구축된다. 프로세스들은 통신하기 위해 상대방의 신원( identity ) 만 알면 된다.
- 연결은 정확히 두 프로세스 사이에만 연관된다.
- 통신하는 프로세스들의 각 쌍 사이에는 정확하게 하나의 연결이 존재해야한다.
위의 방법은 서로의 신원을 알아야 하는 대칭성이다
그와 반대로 비대칭을 사용할 수 있다. 송신자만 수진자의 이름을 지명하여, 수신자는 송신자의 이름을 제시할 필요가 없다.
- send ( P, message ) - 메시지를 프로세스 P에 전송한다.
- receive ( id, message ) - 임의의 프로세스로부터 메시지를 수신한다. 변수 id는 통신을 발생시킨 프로세스의 이름으로 설정된다.
위의 기법들 ( 대칭성, 비대칭성 ) 모두 프로세스를 지정하는 방식 때문에 모듈성을 제한한다. 이름이 바뀌면 모든 참조를 반드시 찾아서 바꿔줘야 한다. 이러한 하드코딩 기법은 신원을 명시적으로 표시해야한다.
간접통신에서 메시지들은 메일박스(mailbox) 또는 포트(port)로 송신되고, 수신된다.
메일박스는 추상적으로 프로세스들에 의해 메시지들이 넣어지고 메시지들이 제거될 수 있는 객체로 볼 수 있다.
각 메일박스는 고유의 id를 가진다.
- send ( A, message ) - 메시지를 메일박스 A로 송신한다.
- receive ( A, message ) - 메시지를 메일박스 A로부터 수신한다.
위의 통신연결은 다음과 같은 특징을 가진다
- 한 쌍의 프로세스들 사이의 연결은 이들 프로세스가 공유 메일박스를 가질 때만 구축된다.
- 연결은 두 개 이상의 프로세스들과 연관될 수 있다.
- 통신하고 있는 각 프로세스 사이에는 다수의 서로 다른 연결이 존재할 수 있고, 각 연결은 하나의 메일박스에 대응된다.
3.6.2 동기화 Synchronization-p145
메시지 전달은 봉쇄형(blocking)이거나 비봉쇄형(nonblocking) 방식으로 전달된다. 이 두 방식은 각각 동기식, 비동기식 이라고도 알려져 있다.
- 봉쇄형 보내기 : 송신하는 프로세스는 메시지가 수신 프로세스 또는 메일박스에 의해 수신될 때까지 봉쇄된다.
- 비봉쇄형 보내기 : 송신하는 프로세스가 메시지를 보내고 작업을 재시작 한다.
- 봉쇄형 받기 : 메시지가 이용 가능할 때까지 수신 프로세스가 봉쇄된다.
- 비봉쇄형 받기 : 송신하는 프로세스가 유효한 메시지 또는 널(null)을 받는다.
send() 와 receive() 와의 다른 조합도 가능하다. send()와 receive()가 모두 봉쇄형일 때, 우리는 송신자와 수신자 간에 랑데부(rendezvous)를 하게 된다.
3.6.3 버퍼링 Buffering -p146
통신이 직접적이든 간접적이든 간에, 통신하는 프로세스들에 의해 교환되는 메시지는 임시 큐에 들어있다.
1. 무용량 ( zero capacity ) :
큐의 최대길이가 0이다. 즉, 링크는 자체 안에 대기하는 메시지들을 가질 수 없다. 이 경우에, 송신자는 수신자가 메시지를 수신할 때까지 기다려야 한다.
2. 유한 용량 ( bounded capacity ) :
큐는 유한한 길이 n을 가진다. 즉, 최대 n개의 메시지가 그 안에 들어 있을 수 있다. 새로운 메시지가 전송될 때 큐가 만원이 아니라면, 메시지는 큐에 놓이며(메시지가 복사되든지 또는 메시지에 대한 포인터가 유지된다), 송신자는 대기하지 않고 실행을 계속한다. 그렇지만, 링크는 유한한 용량을 가진다. 링크가 만원이면, 송신자는 큐 안에 공간이 이용 가능할 때까지 반드시 봉쇄되어야 한다.
3. 무한 용량 ( unbounded capacity ):
큐는 잠재적으로 무한한 길이를 가진다. 따라서 메시지들이 얼마든지 큐안에서 대기할 수 있다 송신자는 절대 봉쇄되지 않는다.
무용량의 경우는 때때로 버퍼가 없는 메시지 시스템이라고 부른다. 다른 경우들은 자동 버퍼링이라 불린다.
3.7 IPC 시스템의 사례 -p146
4가지 다른 IPC 시스템을 탐구한다.
- POSIX API
- Mach
- Windows IPC
- UNIX pipe
3.7.1 POSIX 공유 메모리 -p147
POSIX 공유 메모리는 메모리 -사상 파일을 사용하여 구현된다. 메모리-사상 파일은 공유 메모리의 특정 영역을 파일과 연관시킨다.
fd = shm_pen(name, 0_CREAT | O_RDWR, 0666 );
첫 번째 인자는 공유 메모리 객체의 이름을 지정한다.
두 번째 인자는 객체가 존재하지 않으면 생성되고 (0_CREAT) 객체는 읽기와 쓰기가 가능한 상태로 열린다는 것을 나타낸다(0_RDRW).
마지막 인자는 공유 메모리 객체에 파일-접근 허가권을 부여한다.
shm_open() 이 성공하면 공유 메모리 객체를 나타내는 정수형 파일 설명자를 반환한다.
3.7.2 Mach 메시지 전달 -p149
Mach는 특히 분산 시스템용으로 설계되었지만 2장에서 논의된 것처럼 macOS및 iOS 운영체제에 포함된 사일이 입증하듯이 데스크톱 및 모바일 시스템에도 적합하다.
Mach 커널은 프로세스와 유사하지만 제어 스레드가 많고 관련 자원이 적은 다중 태스크의 생성 및 제거를 지원한다.
Mach는 동일한 송신자의 여러 메시지가 선입선출(FIFO) 순서로 큐에 삽입하지만 절대적 순서를 보장하지는 않는다.
Mach 메세지는 두 필드를 포함한다
- 고정 크기의 메시지 헤더. 헤더는 메시지 크기, 소스 및 대상 포트를 포함한 메시지에 관한 메타 데이터를 포함한다. 일반적으로 송신 스레드는 응답을 예상하므로 소스의 포트 이름이 수신 태스크로 전달되어 응답을 보내는 데 "반환 주소"로 사용할 수 있다.
- 데이터를 포함하는 가변 크기 본체
기본적으로 Mach는 송신자의 메시지가 포함된 주소 공간에 매핑한다. 따라서 송신자와 수신자 모두 동일한 메모리에 액세스 하므로 메시지 자체는 실제로 복사되지 않는다.
3.7.3 Windows -p153
Windows 운영체제는 모듈화를 이용하여 기능을 향상시키고 새로운 기능을 구현하는 시간을 감소시킨 최신 설계의 예이다.
다중 운영 환경 또는 서브시스템을 지원하며, 응용 프로그램은 메시지 전달 기법을 통해 이들과 통신한다. 따라서 응용 프로그램은 서브시스템 서버의 클라이언트로 간주할 수 있다.
Mach와 유사하게, Windows는 두 프로세스 간에 연결을 구축하고 유지하기 위해 포트 객체를 사용한다. Windows는 연결 포트
( connection port ) 와 통신 포트( communication port )의 두 가지 유형의 포트를 사용한다.
Windows의 메시지 전달 설비는 고급 로컬 프로시저 호출 설비 ( advanced local procedure call facility, ALPC)라 불린다.
ALPC는 동일 기계상에 있는 두 프로세스 간의 통신에 사용한다.
ALPC 채널이 생성되면 다음 3가지 중 하나의 메시지 전달 기법의 하나가 선택된다.
- 256 바이트까지의 작은 메시지의 경우, 포트의 메시지 큐가 중간 저장소로 사용되고, 메시지는 프로세스에서 프로세스로 복사된다.
- 대용량 메시지는 반드시 섹션 객체(section object)를 통하여 전달되어야 한다. 섹션 객체란 채널과 연관된 공유 메모리의 영역을 말한다.
- 데이터의 양이 너무 많아서 섹션 객체에 저장될 수 없는 경우, 서버 프로세스가 클라이언트의 주소 공간을 직접 읽거나 쓸 수 있는 API를 사용할 수 있다.
Windows의 고급 로컬 프로시저 호출 설비는 Windows API의 부분이 아니리 때문에 응용 프로그래머는 사용할 수 없다.
3.7.4 UNIX 파이프 -p155
파이프는 두 프로세스가 통신할 수 있게 하는 전달자로서 동작한다. 파이프는 초기 UNIX 시스템에서 제공하는 IPC기법의 하나였다.
pipe를 구현하기 위해 다음 4가지를 고려해야한다.
- 파이프가 단방향 통신 또는 양방향 통신을 허용하는가?
- 양방향 통신이 허용된다면 반이중 ( half duplex) 방식인가, 전이중( full duplex) 방식인가? 반이중 방식은 한순간에 한 방향 전송만 가능하고 전이중 방식은 동시에 양방향 데이터 전송이 가능하다.
- 통신하는 두 프로세스 간에 부모-자식 과 같은 특정 관계가 존재해야만 하는가?
- 파이프는 네트워크를 통하여 통신이 가능한가, 아니면 동일한 기계 안에 존재하는 두 프로세스끼리만 통신할 수 있는가?
3.7.4.1 일반 파이프 - p155
일반 파이프는 생산자-소비자 형태로 두 프로세스 간의 통신을 허용한다. 생산자는 파이프의 한 종단(쓰기 종단)에 쓰고, 소비자는 다른 종단 (읽기 종단)에서 읽는다. 결과적으로 일반 파이프는 한쪽으로만 데이터를 전송할 수 있으며 오직 단방형 통신만을 가능하게 한다. 양방향을 원하면 두 파이프를 써야한다.
일반 파이프는 파이프를 생성한 프로세스 이외에는 접근할 수 없다. 자식 프로세스는 열린 파일을 부모로부터 상속받는다. 파이프는 파일의 특수한 유형이기 때문에 자식 프로세스는 부모로 부터 파이프를 상속 받는다.
3.7.4.2 지명 파이프 -p160
지명 파이프(named pipes)는 좀 더 강력한 통신 도구를 제공한다. 통신은 양방향으로 가능하며 부모-자식 관계도 필요로 하지 않는다. 지명 파이프가 구축되면 여러 프로세스들이 이를 사용하여 통신할 수 있다.
3.8 클라이언트 서버 환경에서 통신 -p161
클라이언트 서버에서 사용할 수 있는 두 가지 다른 통신 전략
1. 소켓
2. 원격 프로시저 호출(RPC)
3.8.1 소켓 Socket -p162
소켓(socket)은 통신의 극점 (endpoint)을 뜻한다. 두 프로세스가 네트워크상에서 통신을 하려면 양 프로세스마다 하나씩, 총 두 개의 소켓이 필요해진다. 각 소켓은 IP 주소와 포트 번호 두 가지를 접합 (concatenate)해서 구별한다.
클라이언트 프로세스가 연결을 요청하면 호스트 컴퓨터가 포트 번호를 부여한다.
모든 연결은 유일 해야한다.
자바는 세 가진 종류의 소켓을 제공한다. 연결 기반(TCP)소켓은 Socket 클래스로 구현된다. 비연결성(UDP) 소켓은 DatagramSocket 클래스를 사용한다. 마지막으로 MulticastSocket 클래스는 DatagramSocket 클래스의 서브클래스이다. Multicast 소켓은 데이터를 여러 수신자에게 보낼 수 있다.
서버가 소켓과 통신하는 법:
서버는 먼저 PrintWriter 객체를 만들고 이 객체는 추후 클라이언트와 통신하는데 사용된다.
PrintWriter 객체는 서버가 print()나 println()과 같은 루틴을 써서 소켓에 데이터를 쓸수 있게 한다.
서버는 println() 메소드를 호출하여 클라이언트에게 날짜를 보낸다. 날짜를 소켓에 쓰면 서버는 이 클라이언트와의 소켓을 닫고 다른 요청을 기다리게 된다.
IP 주소 127.0.0.1은 루프백(loopback)을 나타내는 특별한 IP주소다. 컴퓨터가 이 주소를 참조하면 그 자신 기계를 지칭하는 것이다.
소켓은 스레드 간에 구조화 되지 않은 바이트 스트림만을 통신한다.
3.8.2 원격 프로시저 호출 Remote Procedure Calls, RPC -p164
원격 서비스와 관련한 보편적인 형태 중 하나는 RPC 패러다임으로서, 네트워크에 연결된 두 시스템 사이의 통신에 사용하기 위하여 프로시저 호출 기법을 추상화하는 방법으로 설계되었다.
IPC 방식과는 달리 RPC 통신에서 전달되는 메시지는 구조화되어 있고, 따라서 데이터의 패킷 수준을 넘어서게 된다. 이 문맥에서 포트는 단순히 메시지 패키지의 시작 부분에 포함되는 정수이다. 시스템은 일반적으로 네트워크 주소는 하나씩 가지지만 그 시스템에서 지원되는 여러 서비스를 구별하기 위해 포트를 여러 개 가질 수 있다.
RPC는 클라이언트가 원격 호스트의 프로시저 호출하는 것을 마치 자기의 프로시저 호출하는 것처럼 해준다.
3.8.2.1 Android RPC -p167
Android 운영체제는 바인더 프레임워크에 포함된 풍부한 IPC 기법의 집합을 가지고 있는데, 이 중 RPC는 프로세스가 다른 프로세스의 서비스를 요청할 수 있게 한다.
3.9 요약
1. 프로세스는 실행 중인 프로그램이며 프로세스의 현재 활동 상태는 프로그램 카운터와 다른 레지스터로 나타난다.
2. 메모리에서 프로세스의 레이아웃은 (1) 텍스트 (2) 데이터 (3) 힙 (4) 스택 이 네가지 섹션으로 표시된다.
3. 프로세스가 실행되면 상태가 변경된다. 프로세스의 일반적인 상태는 (1) 준비 (2)실행 (3) 대기 (4) 종료 이다.
4. 프로세스 제어 블록 ( PCB )은 운영체제의 프로세스를 나타내는 커널 데이터 구조이다.
5. 프로세스 스케줄러의 역할은 CPU에서 실행할 수 있는 사용 가능한 프로세스를 선택하는 것이다.
6. 운영체제는 한 프로세스 실행에서 다른 프로세스 실행으로 전환할 때 문맥 교환을 수행한다.
7. fork() 및 CreateProcess() 시스템 콜은 각각 UNIX 및 Windows 시스템에서 프로세스를 생성하는 데 사용된다.
8. 프로세스 간 통신에 공유 메모리를 사용하는 경우 두 개 이상의 프로세스가 동일한 메모리 영역을 공유한다. POSIX는 공유 메모리를 위한 API를 제공한다.
9. 메시지 전달을 사용하여 두 프로세스가 서로 메시지를 교환하여 통신할 수 있다. Mach 운영체제는 프로세스 간 통신의 기본 형태로 메시지 전달을 사용한다. Windows는 메시지 전달 방식도 제공한다.
10. 파이프는 두 프로세스가 통신할 수 있는 통로를 제공한다. 일반 및 지명 파이프의 두 가지 형태가 있다. 일반 파이프는 부모-자식 관계가 있는 프로세스 간의 통신을 위해 설계 되었다. 지명 파이프가 더 일반적이며 여러 프로세스가 통신할 수 있다.
11. UNIX 시스템은 pipe() 시스템 콜을 통해 일반 파이프를 제공한다. 일반 파이프에는 읽기 종단과 쓰기 종단이 있다. 예를 들어, 부모 프로세스는 쓰기 종단을 사용하여 파이프로 데이터를 전송할 수 있으며 자식 프로세스는 읽기 종단에서 데이터를 읽을 수 있다. UNIX에서 지명 파이프를 FIFO라고 한다.
12. Windows 시스템도 익명 및 지명 파이프라는 두 가지 형식의 파이프를 제공한다. 익명 파이프는 UNIX 일반 파이프와 유사하다. 이들은 단방향이며 통신 프로세스간에 부모-자식 관계가 있어야 한다. 지명 파이프는 UNIX의 대응되는 FIFO보다 풍부한 프로세스 간 통신 방식을 제공한다.
13. 클라이언트-서버 통신의 두 가지 일반적인 형태는 소켓과 원격 프로시저 호출(RPC)이다. 소켓을 사용하면 다른 시스템의 두 프로세스가 네트워크를 통해 통신할 수 있다. RPC는 다른 컴퓨터에 있는 프로세스에서 함수를 호출할 수 있는 방식으로 함수(프로시저) 호출 개념을 추상화한다.
14. Android 운영체제는 바인더 프레임워크를 사용하여 프로세스 간 통신의 형태로 RPC를 사용한다.
'개인공부 > 운영체제 공룡책 10판' 카테고리의 다른 글
운영체제 공룡책 - Chapter 5. CPU 스케줄링 (0) | 2020.12.10 |
---|---|
운영체제 - chapter 4. 스레드와 병행성 (0) | 2020.12.01 |
운영체제 - Chapter 2. 운영체제의 구조 (0) | 2020.11.25 |
운영체제 - Chapter1. 서론 (0) | 2020.11.24 |
운영체제 공룡책 10판 - 목차정리 (0) | 2020.11.23 |