운영체제 - ch.03

Jajuna_99·2023년 4월 22일
0

운영체제

목록 보기
4/10

운영체제 - 3장 프로세스

프로세스 개념

프로세스

운영체제는 프로세스 단위로 여러가지위 프로그램을 실행시킨다.

프로세스 : 실행중인 프로그램이다. 프로세스는 순차적인 절차로 실행되어야 한다.

프로세스의 메모리 배치는 여러 부분으로 나뉜다.

  • 텍스트 섹션 : 실행 코드
  • 데이터 섹션 : 전역 변수
  • 현재 활동 상태는 프로그램 카운터 값과 프로세서 레지스터값으로 나뉘어 담긴다.
  • 스택 : 함수를 호출할 떄 임시 데이터 저장장소 (함수 매개변수, 복귀 주소 및 지역 변수)
  • : 프로그램 실행 중에 동적으로 할당되는 메모리

프로그램 자체는 수동적인 존재이고, 명령어 리스트를 내용으로 가진 ㄴ디스크에 저장된 파일이다.

이에 대조적으로 프로세스는 다음에 실행할 명령어를 지정하는 프로그램 카운터와 관련 자원의 집합을 가진 능동적인 존재이다.

프로그램은 메모리에 실행 파일이 적재될 때 프로세스가 된다.

프로그램의 실행은 GUI의 마우스 클릭이나 커멘드 라인에 프로그램 이름을 입력하는 것으로 실행한다.

한 개의 프로그램은 여러 개의 프로세스가 될 수 있다. (여러 사용자가 같은 프로그램을 실행시키는 경우)

프로세스 상태

프로세스가 실행됨에 따라 상태가 변합니다.

  • 새로운(new) : 프로세스가 생성 중
  • 실행(running) : 명령어들이 실행되고 있다.
  • 대기(waiting) : 프로세스가 어떤 이벤트(입출력 완료 or 신호의 수신)가 일어나기를 기다린다.
  • 준비(ready) : 프로세스가 처리기에 할당되기를 기다린다.
  • 종료(terminated) : 프로세스의 실행이 종료

프로세스 제어 블록 (PCB)

PCB : 각 프로세스를 운영체제에서 표현하는 정보

프로세스 상태 : 새로운, 준비, 실행, 대기, 정지
프로그램 카운터 : 프로세스가 다음에 실행할 명령의 주소를 가리킴
CPU 레지스터들 : 중앙 레지스터의 정보들을 포함한다.
CPU 스케줄링 정보 : 프로세스 우선순위, 스케줄 큐에 대한 포인터와 다른 스케줄 매개변수 포함
메모리 관리 정보 : 프로세스에 할당된 메모리 정보들을 볼 수 있다. 운영체제에 의해 사용되는 메모리 시스템에 따라 기준 레지스터와 한계 레지스터의 값, 운영체제가 사용하는 메모리 시스템에 따라 페이지 테이블 또는 세그먼트 테이블 등과 같은 정보를 포함한다.
회계(accounting) 정보 : CPU 사용 신간과 경과된 실시간, 시간 제한, 계정 번호, 잡 또는 프로세스 번호 등을 포함한다.
입출력 상태 정보 : 해당 프로세스에 할당된 입출력 장치들과 열린 파일의 목록 등을 포함한다.

스레드

이제까지 논의한 프로세스 모델은 프로세스가 단일의 실행 스레드를 실행하는 프로그램임을 암시했다.

만약 한개의 프로세스에 여러 프로그램 카운터를 갖고 있다면 여러 주소에서 한 번에 실행시킬 수 있다.

프로세스 개념을 확장하여 한 프로세스가 다수의 실행 스레드를 가질 수 있도록 허용한다.

스레드 정보를 저장할 공간이 필요하고 PCB에 여러 프로그램 카운터가 필요하다

프로세스 스케줄링

CPU 사용을 최대화 하고 프로세스들 사이에서 CPU 코어를 빈번하게 교체하는 것이 목표이다.

프로세스 스케줄러는 코어에서 실행 가능한 여러 프로세스 중에서 하나의 프로세스를 선택한다.

프로세스의 스케줄링 큐를 유지하는 방법

  • 준비 큐 : 모든 프로세스들을 준비 상태가 되어 CPU 코어에서 실행되기를 기다립니다.
  • 대기 큐 : 모든 프로세스들을 대기 상태가 되어 이벤트를 기다립니다.

문맥 교환

문맥 교환은 CPU가 한 프로세스에서 다른 프로세스로 교환할 때 발생합니다.

CPU가 프로세스를 교환하면 시스템은 이전 프로세스의 상태를 저장하고 저장된 상태를 새로운 프로세스를 위해 맥문 교환을 통해 적재해야 한다.

프로세스의 문맥은 PCB에 표현됩니다.

문맥 교환이 진행될 동안 시스템이 아무런 유용한 일을 못 하기 때문에 문맥 교환 시간은 순수한 오버헤드이다. (운영체제와 PCB가 복잡할수록 문맥 교환이 오래 걸린다.)

문맥 교환 시간은 하드웨어의 지원에 크게 좌우된다.

일부 처리기들은 여러 개의 레지스터 집합을 제공한다. 문맥 교환은 단순히 현행 레지스터 집합에 대한 포인터를 변경하는 것을 포함합니다.

프로세스에 대한 연산

프로세스 생성

부모 프로세스는 자식 프로세스를 생성한다. 즉, 트리구조를 띄면서 프로세스는 다른 프로세스를 생성한다.

보통 프로세스는 process identifier(pid)로 식별되고 관리된다.

프로세스 자원 공유 방법 3가지

  • 부모와 자식이 모든 자원을 공유
  • 자식이 부모의 서브셋 자원을 공유
  • 부모와 자식이 자원을 공유하지 않음

두 프로세스를 실행시키는 2가지 방법

  • 부모와 자식이 병행하게 실행을 계속하기
  • 보모는 일부 또는 모든 자식이 실행을 종료할 때까지 기다리기

새로운 프로세스들의 주소 공간 츨면에서 볼 때 다음과 같은 두 가지 가능성이 있다.

  • 자식 프로세스는 부모 프로세스의 복사본이다. (둘다 같은 프로그램과 데이터를 가진다.)
  • 자식 프로세스가 자신에게 적재될 새로운 프로그램을 가지고 있다.

UNIX 예제

  • fork() : 시스템 콜, 새로운 프로세스를 생성합니다.
  • exec() : 시스템 콜, fork() 이후에 사용되고 새로운 프로그램으로 프로세스의 기억 공간을 대체한다.
  • 부모 프로세스가 wait()를 호출해 자식 프로세스를 종료한다.

(부모와 자식 구현 부분 수업 자료 p.24)

프로세스 종료

프로세스가 마지막 단계를 수행하고 운영체제에게 exit() 시스템 콜로 자신을 지워줄 것을 요청합니다.

  • 자식으로부터 부모 에게 상태 데이터를 wait()를 통해 반환합니다.
  • 프로세스의 자원은 운영체제에 의해 할당 취소됩니다.

부모는 자식의 프로세스를 abort() 시스템 콜로 실행을 종료시킬수 있다.

  • 자식이 할당된 자원을 넘겼을 때
  • 주어진 작업이 자식을 더 필요로 하지 않을 때
  • 부모가 존재하고 운영체제가 부모가 종료할 때 자식을 더 이상 존재하지 못하게 할 때
    자식 프로세스를 종료시킨다.

어떤 운영체제들은 부모가 종료되면 자식이 존재하지 못 하게 한다. 만약 프로세스가 종료되면 모든 자식 프로세스가 종료되야 합니다.

연쇄식 종료(cascading termination) : 자식, 손주 등 같이 종료 된다. 종료는 운영체제에 의해 실행된다.

부모 프로세스는 wait() 시스템 콜로 자식 프로세스가 끝날때 까지 기다릴 수 있다. 이 시스템 콜은 프로세스의 pid와 상태 정보를 반환합니다.

pid = wait($status); //자식 중 어느 하나가 종료될 때까지 기다림

만약 대기중인 생태의 부모가 없으면 프로세스는 좀비상태가 된다. (wait()를 실행하지 않았을 때)

만약 부모가 wait를 실행하지 않고 종료한다면 프로세스는 고아가 된다.

안드로이드 프로세스 계층

멀티프로세스 구조 - 크롬 브라우저

하나의 프로그램이 여러 개의 프로세스를 생성하는 구조이다.

프로세스 간 통신

프로세스들은 시스템 내에서 독립적일 수도 있고 협력적일 수도 있다.

협력적인 프로세스들은 다른 프로세스로에게 영향을 주고 받을 수 있다.

협력적인 프로세스가 있는 이유는

  • 정보 공유
  • 계산 속도 증가
  • 모듈성
  • 편리성
    때문이다.

협력적인 프로세스들은 interprocess communication(IPC) 프로세스 간 통신이 필요하다. IPC에는 공유 메모리메시지 전달 두 가지 모델이 있다.

공유 메모리 스시템에서의 프로세스 간 통신

협력적인 프로세스의 일반적인 페러임인 생산자-소비자 문제를 보자

생산자 프로세스는 정보를 생성하고 소비자 프로세스는 이를 소비한다.

무한 버퍼 : 생산자 소비자 문제에서는 버퍼의 크기에 실질적인 한계가 없다.
유한 버퍼 : 버퍼의 크기가 고정되어 있다고 가정한다.

(버퍼가 시장 역할을 한다고 한다.)

통신을 원하는 생산자와 소비자 프로세스간에 공유 메모리 영역이 있다.

운영체제 프로세스가 아닌 사용자 프로세스에 의해 통신이 제어된다.

가장 큰 문제는 사용자 프로세스가 공유 자원에 접근할 때 행위를 동기화 하도록 정책을 만들어야 하는 것이다.

동기화는 6, 7 장에서 다룬다.

메시지 전달 시스템에서의 프로세스 간 통신

메시지 전달을 사용하면 프로세스를 위한 행위 정책: 통신동기화 (IPC의 두가지 용도)를 만들 수 있다.

메시지 시스템 : 시스템끼리 공유 변수를 재정렬하지 않고 공유할 수 있다.

메시지 전달 시스템은 최소한 두가지 연산을 제공한다.

  • send(message)
  • receive(message)

메시지 크기는 고정 길이일 수도 있고 가변 길이일 수도 있다.

만약 프로세스 P 와 Q가 통신한다고 하면

  • 두 프로세스 사이에 통신 링크가 설립되야 한다.
  • 메시지를 send와 receive를 통해 교환해야 한다.

구현 문제로는

  • 링크 설정방법
  • 링크당 허용되는 프로세스의 수
  • 통신에 필요한 링크의 수
  • 링크의 용량
  • 메시지의 크기
  • 양방향이나 단방향

통신 링크의 구현 방법으로는

  • 물리
    • 공유 메모리
    • 하드웨어 버스
    • 네트워크
  • 논리
    • 직접이나 간접 통신
    • 동기화나 비동기화 통신
    • 자동 또는 명시적 버퍼링
      등이 있다.

직접 통신

프로세스들은 서로 명시적으로 명명해야 한다.

  • send(P, message) : send a message to process P
  • reveive(Q, message) : reveive a message from procee Q

통신 링크의 속성

  • 링크는 자동적으로 설립된다.
  • 링크는 정확히 한 짝의 통신 프로세스와 관련되어 있다.
  • 한 짝마다 사이에 정확히 한 개의 링크가 존재한다.
  • 링크는 단방향일수 있지만 보통 양방향이다.

간접 통신

메시지는 메일 박스에서 받아지고 지정할 수 있다. (포트라고도 함)

  • 각 메일박스는 유일한 id가 있다.
  • 프로세스는 같은 메일 박스를 공유해야 통신할 수 있다.

통신 링크의 속성

  • 통신 링크는 오직 공용 메일 박스를 통해 프로세스가 공유해야 설립된다.
  • 통신 링크는 많은 프로세스들과 연관될 수도 있다.
  • 각 짝은 여러 통신 링크를 통해 공유할 수 있다.
  • 통신 링크는 단방향일수도 양방향일수도 있다.

간접 통신 연산

  • 새로운 메일박스(포트)를 생성한다.
  • 메일박스를 통해 메시지를 send나 receive 할 수 있다.
  • 메일박스를 파괴한다.

메일 박스 공유에는 문제점이 있는데 한 개의 프로세스가 메시지를 보내면 어떤 프로세스가 받을지 결정해야 하는 문제가 있다.

해결 방안으로

  • 최대 두개의 프로세스만 통신 링크를 설정
  • 최대 한 개의 프로세스만 통신 연산을 수행하도록 설정
  • 시스템이 임의적으로 리시버를 선택할 수 있도록 설정하고 송신자는 수신자가 누군지 노티 받는다.

동기화

메시지 전달이 봉쇄형이나 비봉쇄형이 될 수 있다.

봉쇄형은 동기식과 비동기식으로 구별된다.

동기식 봉쇄형은

  • Blocking send : 송신자는 메시지가 수신될 때까지 봉쇄된다. (queue를 사용하면 non-blocking 효과)
  • Blocking receive : 수신자는 메시지가 수신 가능할 때까지 봉쇄된다.

비동기식 봉쇄형은

  • non-blocking send : 송시자는 계속해서 메시지를 보낸다. (메시지 손실은 queue로 피할 수 있다.)
  • non-blocking receive : 수신자는 계속 받는다. (유효하거나 빈 메시지도)

서로 다른 조합으로 만들수 있고 둘 다 blocking이라면 rendezvous가 있다.

버퍼링

메시지큐가 통신 링크에 있는 형식이다.

세 가지 방식으로 구현할 수 있다.

  • 무용량 : 통신 링크 큐에 메시지가 없는 경우. 송신자는 리시버를 기다려야 한다. (rendezvous)
  • 유한 용량 : 유한 크기의 메시지 n, 송신자는 링크가 가득 찰 때까지 대기한다.
  • 무한 용량 : 무한한 용량 메시지, 송신자는 대기하지 않는다.

IPC 시스템이 사례

POSIX 공유 메모리

프로세스는 먼저 시스템 콜을 사용해 공유 메모리 객체를 생성해야 한다.

shm_fd = shm_open(name, O_CREAT | O_RDWR, 0666); 
// 공유 메모리 객체의 이름, 객체가 존재하지 않으면 생성하기, 읽기와 쓰기가 가능한 생태로 열기, 0666은 접근 권한

이미 생성된 객레를 열 때도 사용된다.

객체가 설정되면 객체 크기를 바이트 단위로 설정한다.

ftruncate(fd, 4096);

마지막으로 mmap() 함수가 공유 메모리 객체와 파일 포인터를 포함하는 메모리-사상 파일을 구축한다.

공유 메모리에 읽기와 쓰기는 mmap()에서 반환된 포인터로 가능하다.

windows

파이프

파이프는 두 프로세스가 통신할 수 있게 하는 전달자로서 동작한다.

문제점

  • 통신이 단방향이어야 하나 양방향이어야 하나
  • 양방향일 경우 (키보드-simplex, 무전기-half-duplex, 폰-full-duplex)
  • 통신하는 프로세스 간에 (부모-자식) 관계가 있어야 하는가
  • 파이프가 네트워크를 통하여 통신이 가능한가, 아님 같은 기계 안에서만 가능한가

일반 파이프
생성한 프로세스 외에서는 접근이 불가능하다. 특히 부모 프로세스가 자식 프로세스와 통신하기 위해 파이프를 생성한다.

지명 파이프
부모 자식 관계가 아니어도 통신이 가능하다.

클라이언트 서버 환경에서 통신

소켓

소켓은 종단간 통신으로 정의된다.

각 소켓은 IP주소와 포트 번호 두 가지를 접합(concatenate)해서 구별한다. 메시지 패킷에의 시작 부분에 수들이 포함되고 호스트 상의 네트워크 서비스에서 차별을 둔다.

소켓 161.25.19.8:162는 호스트 161.25.19.8에 포트 1625라는 뜻이다.

통신은 한 짝의 소켓을 갖고 있어야 한다.

포트 번호 1024 밑으로는 알려진 번호들이고 표준 서비스들에 사용된다.

IP 주소 127.0.0.1(loopback)은 프로세스가 실행 중인 서비스를 뜻한다.

원격 프로시저 호출

원격 프로시저 호출(RPC)는 프로시저 호출 기법을 추상화하는 방법으로 설계되었다. (포트와 여러 서비스를 사용한다.)

스텁 : 클라이언트 쪽에 프록시를 제공한다. 서버의 진짜 프로시저이다. (라이브러리처럼 호출해서 결과값을 메시지를 전송한다.)

!(프록시 서버는 클라이언트가 자신을 통해서 다른 네트워크 서비스에 간접적으로 접속할 수 있게 해 주는 컴퓨터 시스템이나 응용 프로그램을 가리킨다. )

스텁은 원격 서버의 포트를 찾고 매개변수를 정돈(marshall, 코더로 데이터를 flat, plain하게 만드는 것)한다. (디코더로 unmarshalling 한다.)

서버 측 스텁은 메시지를 수신하고 정돈된 매개변수들을 unpack한다. 그리고 프로시저를 서버에서 수행한다.

profile
Learning bunch, mostly computer and language

0개의 댓글