[운영체제] 3. 프로세스

임호연·2021년 5월 21일
0

기록

목록 보기
3/20
post-thumbnail

프로세스

프로세스의 정의

  • 실행 중인 프로그램이다.
  • 프로그램의 실행 흐름이다.
  • 능동적인 존재다.
  • 메모리나, cpu, I/O 등을 점유하는 상태를 가지는 개체
  • 프로세스의 수 : 다중 프로그래밍 정도라고 볼 수 있다.

프로세스의 정말 간단한 구조

  • Text : Code

  • data : global

  • heap : 동적 할당

  • stack : 함수 실행 흐름

  • heap, stack은 서로 겹치지 않도록 해야 한다.

  • 실제 C의 메모리 관리 기법입니다.

프로세스의 상태

프로세스 블록

  • execution states

  • scheduling information

  • state transition(mode bit)

  • accounting information도,,

    cpu 사용 시간, 경과 시간 등

프로세스 스케줄링에 대한 간략 정보

  • 준비 큐 : 언제든 실행 가능, 연결리스트로 저장.
  • 대기 큐 : I/O를 기다리는 중

  • 갖가지 친구들은 waiting queue 입니다.

Context Switching

  • PCB에다가 이전 상태를 저장하고, 새로운 프로세스의 정보를 PCB에서 가져와서 cpu에 적재한다.

  • 문맥교환시간은 순수한 오버헤드가 된다.

  • Detail

    1. 현재 가리키는 주소(cpu의 current PCB 포인터)의 프로세스 상태, return address 등을 PCB에 저장해놓는다.

      이 때, 하드웨어에서 자동으로 실행하게끔 하는게 좋다.

    2. ISR시작한다.

      해당 ISR은 dispatcher 일 것이다.

    3. register의 값을 PCB에 저장한다.

    4. current PCB 포인터 값을 갱신한다.

    5. 새로운 PCB에 안에 있는 새로운 레지스터를 적재한다.

    6. 실행해야할 instruction의 값을 pcb에서 뽑아온다.

  • 새로운 프로세스를 시작할 땐, 이러한 PCB가 없기 때문에, FAKE STACK을 사용할 수 있다. 그냥 기존 프로세스를 복사하거나, 더미값을 채워넣거나,,

모바일의 다중 태스킹

  • IOS

    • 원래는 다중태스킹 지원 부분적으로만 했지만,,
    • 화면 분할 등 → 다중 프로세서를 지원한다는 의미
  • 안드로이드의 application은 백그라운드 서비스를 이용한다.

    즉, 모바일에서는 application이 당장 실행 안 되어도, 음악 재생 같은게 백그라운드 서비스를 통해 자연스레 실행되도록 할 수 있다.

  • 확장적으로 생각하면, 이렇게 단계를 나눠서 전원관리도 할 수 있겠네.

프로세서의 생성에 대한 고찰

  • 이렇게, 부모가 있는 트리 형태

    fork() system call의 결과가 아닐까.

  • systemMD가 부팅 시작 때 처음으로 시작되어, 다른 프로세스들이 이 systemMD로부터 시작된다.

    SystemMD를 추적하면 프로세스 트리를 얻을 수 있다.

프로세스 생성

  • 프로세스 생성 시

    1. Load data/code(복사만 해라)

    2. create stack /heap→ 프로세스마다 다르므로, runtime시 생성한다.(당연히 부모꺼 복사해서 처음엔 만들겠지)

    3. PCB를 만든다.

    4. ready list에 프로세스를 넣는다.

    5. 실제 wrapping code는 다음과 같다.

      python
      start(arg1, arg2) {
       main(arg1, arg2); // Call program main. exit(); // If main returns, call exit.
       }
  • 오버헤드 줄이기 위해, C/O/W를 이용하겠지.

    처음에는 PCB의 내용을 포인팅만 하고, EXEC시 비로소 만들기.

  • 파일 공유가 쉽다.

    부모프로세스가 열고 있는 파일은 / 변수는 동일하게 자식에서 이용 가능하다.

  • 윈도우에서는,,

    그냥 프로세스를 만든다.

    엄청 많은 인자를 쓴다.

프로세스 종료

  • 프로세스의 마지막에 exit system call

  • kill, terminateprocess(window)등을 통해서

  • 부모가 삭제될 때, cascade를 강제하는 경우.

  • 좀비 프로세스

    자식 프로세스가 종료되었는데,

    →부모 프로세스의 확인을 기다리는 상태

    →부모가 아직 wait를 호출하지 않은 상태

  • 고아 프로세스

    →말 그대로 고아, 그냥 init(systemMD) 프로세스에 붙인다.

    →때에 따라서 꼭 systemMD가 아니여도 붙을 수는 있다.

안드로이드 프로세스 계층

  • 포어그라운드, 가시적 프로세스(포어그라운드의 백서비스), 서비스 프로세스(음악 재생 등 사용자가 식별은 가능한), 백그라운드 프로세스(사용자가 전혀 모를), 빈 프로세스 순으로 프로세스를 내쫓는다.

웹 프로세스 구조 - 크롬

하나의 application이라도 망가지면 웹 브라우저가 멈추지 않기 위함

  • 브라우저 : 디스크, 네트워크 입출력

  • 렌더러 : 탭마다 열리는, html 파싱하고 보여주는 등등

    렌더러가 따로 실행 됨으로써, 다른 렌더러의 고장에 독립적이게 되며, 보안을 위해 샌드박스안에서 실행된다.

  • 플러그인 : 브라우저와 렌더러 연결,

upcall(signal 구현)

  • 시그널 처리 과정

    만약 타이머 인터럽트라면, 타이머 인터럽트 때

    1. 시그널 스택에 현재 돌고있는 프로세스의 정보들을 다 저장해준다. (PC, SP, register 등등)
    2. 시그널 핸들러로 점프시켜서 프로세스를 실행시킴(프로그램 카운터를 signal handler쪽으로 바꿔벌임)
    3. 시그널핸들러가 종료하면 다시 커널로 복귀시킴, 프로세스의 실행흐름을 리셋한다.
    4. 커널이 다시 일반프로세스 실행시킴

프로세스간 통신(IPC)

  • 정보 공유의 측면, 계산 가속화의 측명,: 딥러닝을 생각해라..

  • 공유 메모리

    프로세스가 각각 해당 공유 메모리를 자신의 주소공간에 추가한다.

    !!일반적으로는 안 되는 일이잖아..

  • 메시지 큐 방식

    운영체제가 제공한다.

    오버헤드가 조금 있지만, 많지 않은 양을 사용할 때는 괜찮을 지도 모른다.

IPC중, 메시지 큐 방식에 대한 깊은 설명

  1. 직접 통신

  • 보내는 애는 P를 직접 지정
  • 받는 애는 누구한테 받을 건지에 까지 지정

  • 누구에게 받을 지 까지는 아닌 것까지 가능. 이런 경우에는, ID argument에 어떤 프로세스가 넣어줬는지 하는 정보가 들어갈 수 있다.
  1. 간접 통신
  • 메일 박스나, 포트로 메세지를 저장시키고, 가져간다.

  1. 받고, 보내는 방식
  • blocking send
  • non-blocking send
  • blocking recv
  • non-blocking recv

그냥, 명령 하고 나서 FAIL이 나도 다른 작업을 바로 수행할 수 있는가?에 달림.

  1. 용량에 따른 방식
  • 무용량: 그냥, 송신자는 수신자가 가지고 갈 때 까지 기다린다.
  • 유한용량 : 송신자는, 버퍼 용량이 꽉 차면 기다린다.
  • 무한 용량: 송신자는,그냥 버리고 간다.

예시 - POSIX 공유 메모리

python
fd = shm_open(name, O_CREAT | O_RDWR, 0666); -> name을 적당히 주고, fd를 만들어 준다.
ftruncate(fd, 4096); -> 객체의 크기 지정
mmap -> 실제 fd를 사상시킨다.
MAP_SHARED를 통해 이거를 보는 모든 객체가 이걸 공유하도록 한다.
  • 쓰는 쪽

  • 읽는 쪽

MACH의 예

  • port mapped mailbox를 이용한다. 수신자는 포트 하나를 점유하며, 송신자는 여러 개의 포트를 점유할 수 있다.
  • 내부의 커널들이 mail box를 통해 소통한다. 부트스트랩 서버에 포트를 등록하면, 다른 테스크가 해당 포트를 부트스트랩 서버에서 확인할 수 있다.

윈도의 예

  • 연결포트와 통신포트 사용(advanced local procedure call facility, ALPC)

  • 제일 위에가 연결 포트, client 가 연결 요청을 하면

    서버는 핸들러를 통해 채널을 만들고

    client와 server는 해당 포트를 나눈다. 그리고 통신한다.

  • 작은 메시지는, 포트의 메시지큐 사용

    대용량 메시지는 색션객체 사용, 그냥 공유메모리를 사용한다.

    초 대용량은 직접 접근하는 방식을 사용한다.

  • 응용프로그래머는 이걸 하지는 않음. 단지 운영체제에 이걸 대신 해달라고 요청한다.

파이프

ls > tmp → ls stdout > tmp

zork < solution → zork stdin < solution

ls | grep HH 라는 거는 ls의 stdout이, grep 이라는 거의 stdin이 된다
  1. 일반 파이프(유닉스)
  • 단방향 통신

pipe(fd[]) -> fd에다가 descriptor 생성, fd[0]는 읽기, [1]은 쓰기
  • fork를 통해서만 구현되기에 부모자식간에만 사용 가능
  • 일반 파이프는 단방향이기에, 사용하지 않는 파이프는 닫아야 한다.

  1. 일반 파이프(익명파이프, 윈도우)

비슷하다.

  1. 지명 파이프(유닉스)
  • 반이중통신(즉 양뱡향 동시는 안 되지만 양뱡향은 된다)
  • FIFO파일이라고도 함
  • open, read,write,close등의 파일과 같은,,
  • 바이트 단위
  1. 지명 파이프(윈도우)
  • 전이중통신
  • 바이트 단위, 메시지 단위 가능

소켓

파이프는 다른 기계들 사이에서는 사용 못 했었다는 점을 인지하자.

별 거 없다. 그냥 create socket하고, socket("찍는 주소", 포트) 로 하면 된다.

빅앤디안 리틀앤디안

RPC (REMOTE PROCEDURE CALL)

  • 그니까, 서버열고, 포트열고, 왔다갔다 하려고 하면 여러 기기들의 프로토콜을 동시에 맞추는 게 사실상 너무 어렵다.

  • 어떤 프로세스의 프로시저를 호출할 건지, PORT를 처음에 매치메이커가 알려준다.

  • 결국, 어떤 일을 하는게 조금 더 중요한 작업에서 유용하겠네.

    클라이언트와 서버 사이에서 왔다 갔다 상호작용 해야 하는 경우 적합.

    클라이언트가 데이터를 단순히 받고자 하는 목적이 아니고, 서로 상호작용 해야 할 때.

  • 클라이언트 몰래 하는 기적

    즉, 서버에서 함수가 무조건 실행되므로 동일한 코드를 어떤 디바이스에서도 동시에 실행할 수 있다.

  • STUB은 어떤 추상화를 제공. apPLICATION이 일일이 데이터에 대해 무결성 검사를 할 필요가 없게끔 한다.

안드로이드의 rpc

다른 기종이 아닌 데도 rpc를 한다.

profile
해탈하자

0개의 댓글