3. Processes

초기 컴퓨터는 한 번의 하나의 프로그램만 실행할 수 있었으나, 지금은 실행 중인 프로그램 – 프로세스 여러 개를 실행할 수 있다. 복잡한 운영 체제는 일부 프로세스는 사용자 코드를 실행하고 다른 프로세스는 시스템 코드를 실행한다. 잠재적으로 이 프로세스들은 동시에 실행될 수 있다.

3.1. Process Concept

CPU 활동을 뭐라 부르는가? 초창기 컴퓨터는 작업, 사용자 프로그램, 태스크를 수행했다. 우리들은 이것을 프로세스라고 부른다.

3.1.1. The Process

프로세스는 실행 중인 프로그램이다. 프로세스의 현 상태는 프로그램 카운터의 값으로 표현되고 프로세서의 레지스터의 내용 중 하나이다. 프로세스의 메모리 레이아웃은 대개 복수의 구역들로 나뉜다:

  • 텍스트 섹션 – 실행 파일 코드
  • 데이터 섹션 – 전역 변수
  • 힙 섹션 – 런타임에 동적으로 할당되는 메모리
  • 스택 섹션 – 함수 실행 시의 임시 데이터 저장소

텍스트와 데이터 섹션의 크기는 고정이나 힙과 스택 섹션은 프로그램 실행 중 동적으로 수축되거나 팽창할 수 있다. 함수가 실행될 때 함수 매개변수나 지역 변수, 반환 주소를 포함하는 활성화 기록들이 스택에 푸시되고, 함수가 반환될 때 이는 스택에서 팝된다. 비슷하게, 힙은 메모리가 동적 할당될 때 팽창하고, 메모리가 반환될 때 수축된다. 이는 서로의 방향으로 팽창하지만 운영 체제는 이들이 겹치지 않음을 보장해야 한다.

프로그램은 그 자체로는 프로세스가 아니다. 프로그램은 실행 파일인 수동적 개체고 프로세스는 능동적 개체이다. 프로그램은 실행 파일이 메모리에 로드될 때 프로세스가 된다. 같은 프로그램이 두 개의 프로세스에 연관되어 있더라도 이들은 독립적인 명령문 실행 순서를 가진다. 프로세스가 그 자체로 다른 코드의 실행 환경이 될 수 있다. Java 프로그래밍 환경이 그렇다.

3.1.2. Process state

프로세스가 실행됨에 따라 그 상태가 변한다. 프로세스의 상태는 프로세스의 현재 활동의 일부분으로 정의되며, 다음의 상태를 가진다.

  • New. 프로세스가 생성되는 중.
  • Running. 명령문이 실행되는 중.
  • Waiting. 이벤트 수행을 기다리는 중.
  • Ready. 프로세서에 할당됨을 기다리는 중.
  • Terminated. 실행이 종료됨.

이 이름들은 운영체제에 따라 다를 수 있다. 한 프로세서 코어에서 실행 중인 프로세스는 오직 한 시점에 하나뿐이다.

3.1.3. Process Control Block

각 프로세스는 운영 체제에 의해 프로세스 제어 블록(PCB) 내지는 태스크 제어 블록으로 표현된다. 이는 다음으로 구성된다.

  • 프로세스 상태.
  • 프로그램 카운터. 다음 명령어의 주소를 담음.
  • CPU 레지스터. 레지스터는 컴퓨터 아키텍쳐에 따라 그 수와 타입이 달라진다. 이는 인터럽트가 발생할 때 저장되어야 한다.
  • CPU 스케쥴링 정보. 프로세스의 우선 순위, 스케쥴링 큐에 대한 포인터, 다른 스케쥴링 매개변수.
  • 메모리 관리 정보. 기반과 한계 레지스터의 값, 페이지 테이블, 세그먼트 테이블.
  • 통계 정보. CPU/실제 시간 사용량, 시간 제한, 작업 및 프로세스 번호 등.
  • 입출력 상태 정보. 프로세스에 할당된 입출력 디바이스, 열린 파일들 등.

3.1.4. Threads

프로세스는 실행의 단일 스레드를 수행하는 프로그램이다. 대부분의 현대 운영 체제는 프로세스의 개념을 여러 스레드를 실행할 수 있도록 확장시켰다. 이는 멀티코어 시스템에서 여러 스레드를 병렬로 수행할 수 있을 때 유용하다.

3.2. Process Scheduling

프로세스 스케쥴러는 코어에서 실행할 적절한 프로세스를 선택한다. 동시에 실행 가능한 프로세스의 수는 코어의 수와 같다. 메모리에 있는 프로세스의 수를 멀티프로그래밍의 차수라 한다. 이의 균형을 맞추는 것은 프로세스의 특성에 따라 달라진다. 입출력 바운드 프로세스는 입출력에 시간을 많이 쓰는 프로세스고 CPU 바운드 프로세스는 CPU 계산에 시간을 많이 쓰는 프로세스다.

3.2.1. Scheduling Queues

프로세스가 준비되면 이는 준비 큐에 넣어진다. 이 큐는 일반적으로 연결 리스트로 저장된다. 이 큐의 헤더는 첫 번째 프로세스 제어 블록에 대한 포인터를, 각각의 프로세스 제어 블록은 다음 프로세스 제어 블록에 대한 포인터를 담는다. 입출력 등을 대기하는 프로세스를 넣는 또 다른 큐를 대기 큐라 한다. 프로세스 스케쥴링의 표현은 큐 다이어그램이다. 새 프로세스는 준비 큐에 넣어진 뒤 실행 대상으로 선택될 때, 즉 디스패치될 때까지 기다린다. 프로세스가 CPU 코어에 할당되어 실행되면 여러 동작 중 하나가 발생한다.

  • 프로세스가 입출력 요청을 보내고 입출력 대기 큐에 넣어진다.
  • 새 자식 프로세스를 생성하고 자식 프로세스의 종료 때까지 대기 큐에 넣어진다.
  • 인터럽트나 타임아웃이 됨에 따라 코어에서 제거되어 준비 큐로 복귀한다.

3.2.2. CPU Scheduling

CPU 스케쥴러의 역할은 준비 큐에 있는 프로세스를 선택해 CPU 코어를 할당한다. 어떤 운영 체제는 스케쥴링의 중간 형태로 스와핑을 구현하기도 한다. 이는 메모리에서 프로세스를 필요할 때 제거하는 것이다.

3.2.3. Context Switch

인터럽트는 CPU 코어를 현재 태스크에서 커널 루틴으로 변환시킨다. 이는 빈번하게 일어나며, 이럴 때마다 시스템은 실행 중 프로세스의 컨텍스트상태 저장한 뒤 프로세스가 재개될 때 상태 복원을 해야 한다. 이를 컨텍스트 전환이라 한다. 이는 순수한 오버헤드이며, 이 시간은 하드웨어 지원에 의존적이다. 운영 체제가 복잡할 수록 컨텍스트 전환 비용도 비싸진다. 또한 메모리 관리 방법에 따라 달라질 수 있다.

3.3. Operations on Processes

프로세스 생성과 종료 메커니즘을 알아보자.

3.3.1. Process Creation

프로세스는 자식 프로세스를 생성해 프로세스의 트리를 만들 수 있다. 운영 체제는 프로세스를 프로세스 식별자(pid)로 구분한다. Linux에서 systemd 프로세스는 항상 pid = 1이며 모든 사용자 프로세스의 루트가 된다. 또한 가장 먼저 생성된다. UNIX와 Linux 시스템에서는 ps 명령으로 프로세스의 목록을 얻을 수 있다.

자식 프로세스는 자원을 운영 체제로부터 직접 얻을 수도 있고 부모 프로세스가 쓰는 자원에 한정되도록 제한될 수도 있다. 후자의 접근은 너무 많은 자식 프로세스를 오버로딩하는 것을 막는다. 부모 프로세스는 자식 프로세스의 초기화 데이터를 전할 수 있다. 프로세스가 다른 프로세스를 생성할 때에는 두 가지 가능성이 있다.

  1. 부모 프로세스가 자식 프로세스와 동시에 실행된다.
  2. 부모 프로세스가 자식 프로세스 중 일부 또는 전부가 종료될 때까지 대기한다.

새 프로세스의 주소 공간에 대해서도 두 가지 가능성이 있다.

  1. 자식 프로세스가 부모 프로세스의 복제이다.
  2. 자식 프로세스는 별개 프로그램을 로딩한다.

UNIX에서는 fork(), exec() 시스템 호출이 쓰인다. fork()은 새 프로세스를 만들고 exec()는 프로세스의 메모리 공간을 새 프로세스로 대체한다. 윈도우에서는 CreateProcess()로 프로세스를 만들고 WaitForSingleObject()로 프로세스를 기다린다.

3.3.2. Process Termination

프로세스는 마지막 명령문을 실행했을 때 exit() 시스템 호출을 실행하여 운영 체제에 자신을 삭제할 것을 요청한다. 이는 부모 프로세스에 의해 실행될 수도 있으며, 사용자나 잘못된 실행이 타 사용자의 프로세스를 죽일 수도 있다. 부모 프로세스가 자식 프로세스를 종료하는 이유들은 다음과 같다:

  • 자식 프로세스가 할당된 자원을 초과로 사용했을 때.
  • 자식에게 할당된 태스크가 더 이상 필요하지 않을 때.
  • 부모가 종료되고, 운영 체제가 부모가 종료될 시 자식의 실행을 허용하지 않을 때. 이를 연속적 중단이라 한다.

종료되었으나 부모가 wait()을 호출하지 않은 프로세스를 좀비 프로세스라 한다. 모든 프로세스는 종료될 때 좀비 프로세스의 과정을 거치나 대부분은 매우 짧은 시간동안만 그럴 뿐이다. 부모가 wait()를 호출하지 않고 종료되어 버리면 자식은 고아 프로세스가 된다. UNIX 시스템은 init을 새 부모로 만들고 주기적으로 wait()를 호출한다.

3.3.2.1. Android Process Hierarchy

Android는 프로세스에 중요도 계층을 둔다. 이 계층 구성은 다음과 같다:

  • 전경 프로세스. 스크린에 보이는 현재 프로세스. 사용자와 현재 상호 작용 중.
  • 가측 프로세스. 스크린에 직접적으로 보이지는 않지만 전경 프로세스가 참고하는 작업을 수행 중.
  • 서비스 프로세스. 배경 프로세스와 비슷하나 사용자에게 보이는 작업을 수행하는 프로세스.
  • 배경 프로세스. 사용자에게 보이지 않는 작업을 수행하는 프로세스.
  • 빈 프로세스. 실행 중인 애플리케이션이 할당되지 않은 프로세스.

Android는 자원이 필요할 때 중요도에 따라 이를 종료한다.

3.4. Interprocess Communication

독립적인 프로세스는 다른 실행 중인 프로세스와 데이터를 공유하지 않는 프로세스다. 협업적인 프로세스는 다른 실행 중인 프로세스에 영향을 미치거나 영향을 받을 수 있다. 이는 다음과 같은 이유에서 지원된다.

  • 정보 공유.
  • 연산 속도 향상.
  • 모듈화.

협업적 프로세스는 프로세스간 통신(IPC)를 필요로 한다. 이에는 두 가지 방법이 있는데 공유 메모리메시지 전송이다. 메시지 전송은 작은 양의 데이터를 전송하는 데 유용하다. 공유 메모리는 메시지 전송보다 빠르다.

3.5. IPC in Shared-Memory Systems

공유 메모리를 사용한 프로세스간 통신은 공유 메모리를 설립하는 것을 필요로 한다. 대개 이 영역은 공유 메모리 세그먼트를 생성한 프로세스의 주소 공간에 위치하며, 이를 사용하려는 프로세스는 이 주소 공간에 부착되어야 한다. 공유 메모리에 써지는 데이터와 장소는 이 프로세스에 의해 판정되며 운영 체제의 통제를 받지 않는다. 이 프로세스는 또한 데이터 레이스가 발생하지 않음에 대한 책임을 가져야 한다.

생산자는 정보를 생산하고 소비자는 그 정보를 소모한다. 생산자-소비자 모델에 공유 메모리를 쓸 수 있는데, 무제한 버퍼는 버퍼의 크기에 제한을 두지 않는다. 제한된 버퍼는 버퍼의 크기가 정해져 있다. 이 경우 소비자는 버퍼가 비었을 경우, 생산자는 버퍼가 꽉 찼을 경우 대기해야 한다.

3.6. IPC in Message-Passing Systems

메시지 전송을 사용한 프로세스간 통신은 같은 메모리 공간을 공유하지 않고 프로세스간 통신을 가능케 한다. 이는 분산형 환경에 유용하다. 이는 메시지 전송/수신을 지원해야 한다. 프로세스 P, Q가 통신하려면 통신 연결이 필요하다. 이는 다음과 같이 구현된다.

  • 직접/간접적 통신
  • 동기/비동기 통신
  • 자동/명시적 버퍼링

3.6.1. Naming

직접 통신은 각 프로세스는 통신하기 원하는 프로세스를 명시적으로 인자로 담는다. 이는 다음 특성을 갖는다.

  • 통신하기 원하는 모든 프로세스의 쌍에 대해 연결이 성립된다.
  • 연결은 2개의 프로세스간에만 성립된다.
  • 2개의 프로세스간에는 단 하나의 연결만 성립된다.

이는 대칭적 어드레싱이다. receive()에서 전송자의 인자를 받지 않는 구현을 비대칭적 어드레싱이라 한다. 단점은 모듈화가 제한되어 있다는 점이다. 프로세스의 식별자를 바꾸려면 다른 모든 프로세스의 정의부를 살펴봐야 한다. 하드 코딩된 경우 더 문제가 된다.

간접 통신은 메시지는 포트를 통해 전송/수신된다. 이는 다음의 특성을 갖는다.

  • 프로세스 쌍이 연결을 가질 때는 같은 메일박스를 공유할 때이다.
  • 연결은 다수의 프로세스간에 성립될 수 있다.
  • 2개의 프로세스간에 여러 개의 연결이 성립될 수 있다.

복수의 프로세스가 하나의 메일박스로부터 receive()를 받으면 어떻게 될까? 어떤 구현을 선택하는지에 따라 다르다.

  • 연결이 최대 2개의 프로세스간에만 성립되게 하는지
  • receive()를 실행할 프로세스를 최대 하나만 두게 하는지
  • 시스템이 임의로 선택하게 하는지

메일박스는 프로세스나 운영 체제에 속할 수 있다. 프로세스에 속할 경우 소유자와 사용자를 구분해야 한다. 이 경우 소유자가 끝나면 메일밗도 사라진다. 운영 체제에 속하는 메일박스의 경우 다음 메커니즘을 제공해야 한다.

  • 새 메일박스를 생성한다.
  • 메일박스를 통해 메시지를 보내거나 받는다.
  • 메일박스를 제거한다.

3.6.2. Synchronization

메시지 전송은 블로킹(동기) 또는 논블로킹(비동기)일 수 있다.

  • 블로킹 전송. 전송 프로세스는 메시지가 메일박스나 수신 프로세스에 의해 받아질 때까지 중단된다.
  • 비블로킹 전송. 전송 프로세스는 메시지를 전송하고 동작을 재개한다.
  • 블로킹 수신. 수신 프로세스는 메시지가 가능해질 때까지 중단된다.
  • 비블로킹 수신. 수신 프로세스는 올바른 메시지나 널 메시지를 받는다.

전송과 수신이 모두 블로킹일 때 전송자와 수신자 사이에 랑데부가 있다고 한다.

3.6.3. Buffering

메시지는 임시 큐에 저장된다. 이런 큐는 3가지 방법으로 구현된다.

  • 영 용량. 용량이 0이다. 이 경우 전송자는 수신자가 메시지를 받을 때까지 중단된다.
  • 제한된 용량. 용량이 유한하다. 전송자는 큐가 꽉 차있지 않는 한 중단되지 않는다.
  • 무제한 용량. 전송자는 중단되지 않는다.

영 용량은 버퍼링이 없다고 한다.

3.7. Examples of IPC Systems

프로세스간 통신 시스템의 예제를 알아보자.

3.7.1. POSIX Shared Memory

POSIX에서는 공유 메모리도 가능하고 메시지 전송도 가능하다. 공유 메모리는 shm_open()으로 먼저 공유 메모리를 생성해야 한다. ftruncate()는 오브젝트의 사이즈를 정의한다. mmap()은 공유 메모리에 대한 메모리 매핑을 설립한다. 생산자는 여기에 sprintf()로 메시지를 쓰고 소비자는 이를 읽은 뒤 shm_unlink()로 공유 메모리 세그먼트를 제거한다.

3.7.2. Mach Message Passing

Mach에서 대부분의 통신은 포트를 통한 메시지를 통해 이루어진다. 포트에는 포트와 상호작용하기 위한 권한의 모음인 포트 권한이 연결되어 있다. 태스크가 생성될 때 2개의 특수 포트인 태스크 셀프 포트와 알림 포트가 만들어진다. 커널은 태스크 셀프 포트에 대한 권한을 가져서 태스크가 커널로 메시지를 전송할 수 있게 한다. 커널은 태스크의 알림 포트로 메시지를 전송한다.

mach_port_allocate()는 새 포트를 형성하고 그 메시지 큐에 대한 공간을 할당한다. 각 태스크는 붓스트랩 포트에 대한 접근 권한을 가지며 이는 태스크가 시스템 범위의 붓스트랩 서버에 의해 만들어진 포트에 등록할 수 있도록 한다. 각 포트에 할당된 큐는 유한하다. 메시지는 헤더와 데이터를 멤버로 가진다. 메시지는 간단할 수도 있고 복잡할 수 있는데 간단한 메시지는 구조화되지 않은 데이터이며 복잡한 메시지는 데이터를 담은 메모리 장소에 대한 포인터를 담는다. mach_msg()는 메시지를 전송/수신하는 표준 API이다. 이는 mach_msg_trap() 시스템 호출을 수행해 mach_msg_overwrite_trap()을 호출해 메시지를 실제로 전송한다. 포트의 큐가 꽉 차있으면 전송자는 다음 중 하나를 수행한다.

  • 큐가 빌 때까지 대기한다.
  • 최대 n 밀리초만큼 대기한다.
  • 대기하지 않고 리턴한다.
  • 메시지를 임시로 캐싱해 둔다.

마지막 선택지는 서버 태스크에 쓰인다. 메시지 시스템의 단점은 성능 문제인데 Mach는 가상 메모리 관리 방법으로 이를 개선한다.

3.7.3. Windows

윈도우는 서브시스템을 지원한다. 윈도우 내 메시지 전송 기능은 전문 국소적 프로시져 호출(ALPC)로 이루어진다. 이는 원격 프로시져 호출(RPC)와 비슷하나 윈도우에 최적화되어 있다. 윈도우는 연결 포트통신 포트의 2가지 타입을 사용한다.

서버 프로세스는 연결 포트를 설립해 모든 프로세스에 보이게 한다. 클라이언트가 서브시스템의 서비스를 원할 때에는 서버의 연결 포트를 열어 연결 요청을 보낸다. 그러면 서버는 채널을 만들어 클라이언트에게 핸들러를 보낸다. 채널은 클라이언트-서버 메시지 포트와 서버-클라이언트 메시지 포트의 쌍으로 이루어진다. 통신 채널은 콜백 메커니즘도 지원한다.

ALPC 채널이 생성될 때 3가지 메시지 전송 기법 중 하나가 쓰인다.

  • 작은 메시지에 대해서는 포트의 메시지 큐가 쓰인다.
  • 큰 메시지는 영역 객체를 통해 전송된다.
  • 영역 객체에 쓸 수 없을 만큼 큰 데이터는 서버 프로세스가 클라이언트의 주소 공간에 직접 데이터를 쓰게 하는 API가 가능하다.

클라이언트는 이 중 어떤 것을 쓸지를 결정해야 한다. ALPC는 윈도우 API의 일부분이 아니다. 윈도우 API는 일반적인 원격 프로시져 호출을 수행한다.

3.7.4. Pipes

파이프는 두 프로세스간 연결 고리이다. 이를 구현할 때에는 4가지 이슈가 있다.

  1. 파이프가 양방향 통신을 지원하는가? 아니면 통신이 단방향인가?
  2. 양방향 통신이 허용될 경우 데이터가 동시에 양방향으로 흐를 수 있나? 아니면 한 번에 한 방향으로만 흐를 수 있나?
  3. 통신하는 프로세스간 관계가 존재하는가?
  4. 파이프가 네트워크를 통해 통신하는가? 아니면 같은 기기 상에 통신하는가?

3.7.4.1. Ordinary Pipes

일반 파이프는 두 프로세스가 일반적인 생산자-소비자로 통신하게끔 한다. 생산자는 쓰기 끝에 쓰고 소비자는 읽기 끝에서 읽는다. 이는 단방향이며 양방향 통신을 지원하려면 파이프가 2개 필요하다. UNIX 시스템에서는 pipe()로 파이프가 만들어지고 read(), write()로 접근될 수 있다. 일반적으로 부모 프로세스가 파이프를 만들고 fork()한 자식 프로세스와 파이프로 통신한다. 두 프로세스 모두 최초에는 미사용된 파이프 끝부분을 닫아야 한다.

일반 파이프는 윈도우 시스템에서는 익명 파이프로 구현되며 ReadFile(), WriteFile(), CreatePipe(), GetStdHandle() API를 쓴다.

일반 파이프는 부모-자식 관계를 필요로 한다. 즉 같은 머신 내에서의 프로세스간 통신만 가능하다.

3.7.4.2. Named Pipes

일반 파이프에 비해 지명 파이프는 더 강력하다. 양방향일 수도 있고 부모-자식 관계를 필요로 하지 않는다. UNIX 시스템에서는 mkfifo(), open(), read(), write(), close() API를 쓴다. 윈도우에서는 CreateNamedPipe(), ConnectNamedPipe(), ReadFile(), WriteFile() API를 쓴다.

3.8. Communication in Client-Server Systems

여기서는 소켓과 원격 프로시져 호출을 알아본다.

3.8.1. Sockets

소켓은 통신의 끝점으로 정의된다. 네트워크를 통해 통신하는 프로세스 쌍은 프로세스당 하나씩 소켓의 쌍을 갖는다. 이는 IP 주소로 특정된다. 일반적으로 소켓은 클라이언트-서버 아키텍쳐를 사용한다.

Java는 3가지의 다른 소켓을 제공한다. 연결형(TCP)는 Socket으로, 비연결형(UDP)는 DatagramSocket으로, 그리고 복수의 수신자를 지원하는 MulticastSocket을 지원한다.

IP 127.0.0.1은 루프백으로 그 자신을 지칭한다.

소켓은 저수준 통신으로 여겨지는데 프로세스간 통신하는 데이터가 구조화되어있지 않기 때문이다. 구조를 주는 것은 사용자의 몫이다.

3.8.2. Remote Procedure Calls

원격 프로시져 호출은 네트워크간 메시지 기반 통신이다. 프로세스간 통신과 다르게 원격 프로시져 호출에서 교환되는 메시지는 구조화되어 있으며 단순한 데이터 패킷이 아니다. 여기서 포트는 메시지 패킷의 시작 부분에 포함된 숫자이다. 원격 프로시져 호출은 클라이언트에 스텁을 제공함으로써 클라이언트가 원격 호스트에 프로시져를 국소적으로 실행한 것과 같은 효과를 내게 한다. 이 스텁은 서버에 포트를 위치시키고 매개변수를 집행한다. 그리고 서버에 메시지를 전송한다. 서버 쪽의 스텁은 메시지를 받아 서버에서 프로시져를 실행한다. 윈도우에서 스텁은 마이크로소프트 인터페이스 정의 언어(MIDL)로 쓰여진다.

매개변수 집행은 클라이언트와 서버 기기간 데이터 표현의 차이를 고려해야 한다. 빅-엔디언이나 리틀-엔디언간 차이 등. 이를 위해 많은 원격 프로시져 호출 시스템은 기기 독립적인 외부 데이터 표현(XDR)을 갖는다.

또 다른 중요한 이슈는 호출의 시맨틱이다. 운영 체제는 메시지는 최대 한 번이 아닌 정확히 한 번 수행되도록 보장해야 할 필요가 있다. 이를 통해 ACK 메시지를 사용한다.

또 다른 중요한 이슈는 서버와 클라이언트간 통신이다. 클라이언트가 서버의 포트 번호를 어떻게 알 수 있을까? 공유 메모리가 없는데. 두 가지 접근법이 있다. 바인딩되는 정보를 미리 정해 놓거나 매치메이커라는 데몬이 랑데뷰 메커니즘으로 동적 바인딩을 수행하는 것이다. 이것은 더 오버헤드가 있지만 더 유연하다.

원격 프로시져 호출 방식은 분산형 파일 시스템을 구현하는 데 유용하다. 이는 원격 프로시져 호출 데몬과 클라이언트의 집합으로 구현될 수 있다.

3.8.2.1. Android RPC

Android 운영 체제는 바인더 프레임워크 내에 프로세스간 통신 메커니즘을 다수 포함하고 있다. Android는 애플리케이션 컴포넌트를 애플리케이션의 구성 요소로 사용하며, 서비스는 그 중 하나이다. 이는 bindService(), onBind() 등의 API를 통해 사용된다.

3.9. Summary

  • 프로세스는 실행 중인 프로그램으로, 프로세스의 현 활동의 상태는 다른 레지스터들과 함께 프로그램 카운터로 표현된다.
  • 메모리 내 프로세스의 레이아웃은 4개의 다른 영역으로 표현된다. 텍스트, 데이터, 힙, 스택.
  • 프로세스가 실행될 때는 상태가 바뀐다. 4개의 상태가 있다. 준비, 동작, 대기, 종료.
  • 프로세스 제어 블록은 커널 자료 구조로 운영 체제 내의 프로세스를 표현한다.
  • 프로세스 스케쥴러의 역할은 CPU에서 동작 가능한 프로세스를 선택한다.
  • 운영 체제는 한 프로세스에서 다른 프로세스로 전환할 때 컨텍스트 전환을 한다.
  • fork()와 CreateProcess()는 프로세스를 생성한다.
  • 프로세스간 통신에서 공유 메모리가 쓰일 때에는 2개 이상의 프로세스가 같은 메모리 영역을 공유한다.
  • 2개의 프로세스는 메시지 교환을 통해 통신할 수 있다. Mach 운영 체제는 이를 주로 사용한다.
  • 파이프는 두 프로세스의 통신간 연결 고리 역할을 한다. 일반 파이프와 지명 파이프가 있다. 일반 파이프는 부모-자식 관계 프로세스간 통신을 위해 설계되었다. 지명 파이프는 더 일반적이고 복수의 프로세스가 통신할 수 있도록 한다.
  • UNIX 시스템은 pipe()로 일반 파이프를 제공한다. 이는 읽기 끝과 쓰기 끝을 가진다.
  • 윈도우 시스템은 익명 파이프와 지명 파이프를 가진다. 익명 파이프는 단방향이고 부모-자식 관계를 요구한다. 지명 파이프는 더 강력하다.
  • 클라이언트-서버 통신의 2개의 주된 형테는 소켓과 원격 프로시져 호출이다. 소켓은 다른 기기간 두 프로세스가 네트워크를 통해 통신할 수 있게 한다. 원격 프로시져 호출은 함수(프로시져) 호출의 개념을 추상화해 함수가 다른 컴퓨터에 있을 수 있는 다른 프로세스를 실행하도록 한다.
  • Android 운영 체제는 원격 프로시져 호출을 바인더 프레임워크를 이용해 프로세스간 통신의 형태로 쓴다.

답글 남기기

아래 항목을 채우거나 오른쪽 아이콘 중 하나를 클릭하여 로그 인 하세요:

WordPress.com 로고

WordPress.com의 계정을 사용하여 댓글을 남깁니다. 로그아웃 /  변경 )

Google photo

Google의 계정을 사용하여 댓글을 남깁니다. 로그아웃 /  변경 )

Twitter 사진

Twitter의 계정을 사용하여 댓글을 남깁니다. 로그아웃 /  변경 )

Facebook 사진

Facebook의 계정을 사용하여 댓글을 남깁니다. 로그아웃 /  변경 )

%s에 연결하는 중