Process Management(2)

최동혁·2022년 12월 8일
0

운영체제

목록 보기
9/10

Copy-On-Write (COW)

  • 리눅스 체제에서는 부모 프로세스가 자식 프로세스를 생성했다고 자원을 전부 다 새로 복사해서 생성하지 않음.
  • 일단 공유할 수 있는 부분은 최대로 공유함.
  • COW는 write가 발생했을 때 그 때 copy를 하겠다는 얘기.
  • write가 발생한다는 것은 원래 있던 내용을 바꾸는 것임.
  • 그래서 내용이 바뀔 때, 그 이전 내용을 copy해서 새로운 것을 만들고 그 이전까지는 부모의 자원들을 공유하고 있음.
    • 메모리 낭비를 최소화 하기 위해서.
  • 프로세스를 만드는 것은 보통 일이 아니기 때문에 시스템 콜을 이용해 운영체제에게 대신 자식 프로세스를 만들어 달라고 요청.
    • 그것이 바로 fork() 시스템 콜.
      • 부모의 것을 모두 copy.
      • 그렇다면 컴퓨터 상에서 다 똑같은 프로세스만 돌아감.
      • 일단 복제 생성을 한 후, 필요한 경우 새로운 프로그램을 덮어 씌움.
      • 그게 exec() 시스템 콜.
      • 템플릿 같은 느낌임.
      • 기존 틀이 있어서 그것을 먼저 복사해 놓고, 새로운 것을 거기에 덮어 씌우면서 다른 결과물로 만드는 것.

fork() 시스템 콜

  • A process is created by the fork() system call.
    • creates a new address space that is a duplicate of the caller.

  1. fork()를 해서 새로운 프로세스 생성
    • 옆에 똑같은 코드가 하나 더 생긴다고 생각.
  2. 함수 실행이 끝나면, 부모 프로세스는 아무일 없다는 듯이 아래 코드들을 수행.
  3. 자식 프로세스는 fork()를 수행한 이후 시점부터 수행을 하게 된다.
    • fork()를 하면 context를 그대로 복사함.
    • 그러면 Program Counter가 fork()쪽을 가리키고 있는데, fork()를 실행하고 context가 fork()가 끝났을 때쯤으로 이르렀음.
    • 그렇다면 자식 프로세스는 그 context를 복사했기 때문에 다음 PC가 가리키는 코드를 실행함.
      3.1 여기서 문제는 복제를 하게 되면 자신이 원본이라고 주장할 수도 있음.
      3.2 복제를 하면 부모랑 똑같은 것이 만들어져서 세상의 모든 프로그램들은 모두다 똑같은 제어 흐름을 따라가야할것 같음.
  4. 위의 3.1, 3.2의 문제들을 막기 위해 fork()를 하게 되면 부모와 자식을 구분해줌.
    • fork()라는 함수의 return value가 다름.
    • 부모 프로세스는 fork()를 하고 나면 return value가 양수임.
      - 정확하게는 자식 프로세스의 pid 값을 받게 됨.
      • 부모 자식간의 관계를 구분하기 위함!(pid)
    • 자식 프로세스는 fork()를 한 결과값으로 0을 받게됨.
  5. 그리고 복제 해서 3.2의 말처럼 같은 흐름으로 나아간다면 다 같은 프로세스이기 때문에 다른 프로그램도 실행 시킬 수 있어야함. 그것이 바로 exec() 시스템 콜

exec() 시스템 콜

  • 어떤 프로그램을 완전히 새로운 시스템으로 태어나게 해주는 시스템 콜이다.

  • fork()를 통해 자식 프로세스 생성
  • 부모 프로세스라면 결과값이 양수인 부분이 실행
  • 자식 프로세스는 child 프린트를 출력
  • 그런 다음 execlp()를 수행하게 되는데, 이것이 결국은 exec() 시스템 콜임.
  • 자식 프로세스는 위의 코드를 실행하는 프로그램이 되다가, exec() 시스템 콜을 만나면 위의 코드의 기억들은 전부 잊어버리고, 새로운 프로그램으로 덮어씌우게 됨.
  • 그래서 위의 코드에서 execlp의 파라미터 안에 있는 프로그램의 시작부분부터 실행을 하는 것임.
  • 갓난아기가 되서 다시 순수한 기억을 가지고 새로운 출발을 하는 것.
  • fork()는 갓난아기가 아닌 이미 커버린 사람을 복제해서 순수하지 않은 기억을 가지고 행동하는 복제.
  • 그래서 한번 exec()을 하게 되면 되돌아 올 수 없다.

  • exec()은 굳이 자식 프로세스를 만들지 않고도 실행할 수 있다.
  • 그렇게 되면 exec() 이후의 코드는 실행이 불가능하다.
  • 왜냐? 다시 돌아올 수 없기 때문.

wait() 시스템 콜

  • 프로세스 A가 wait() 시스템 콜을 호출하면
    • 커널은 child가 종료될 떄까지 프로세스 A를 sleep시킨다 (block 상태)

      • 보통 block 상태는 오래걸리는 이벤트를 기다리고, 이벤트가 만족이 되면 다시 CPU를 얻을 수 있는 ready 상태로 돌아옴.
      • wait() 시스템 콜은 자식 프로세스를 만든 다음 wait() 시스템 콜을 하게 됨.
      • 그렇게 되면 자식 프로세스가 종료되기를 기다리면서 wait() 되는 것임.
    • Child process가 종료되면 커널은 프로세스 A를 깨운다 (ready 상태)

  • 부모 프로세스가 fork() 시스템 콜을 하게 되면 자식 프로세스도 주소 공간이 만들어짐.
  • 위의 코드는 자식 프로세스라면 자식 프로세스의 코드를 수행하고, 부모 프로세스라면 나머지 코드를 수행하게 됨.
    • 그런데 부모 프로세스 코드에 wait() 시스템 콜을 넣어준다면 부모 프로세스는 block 상태가 되서 CPU를 얻지못하고 잠들게 된다.
    • 자식 프로세스의 코드가 전부 실행이 되면 그 때 부모 프로세스가 wait() 시스템 코드를 빠져나가서 다음 코드를 실행할 수 있음.

exit() 시스템 콜

  • 프로세스의 종료
    • 자발적 종료
      • 마지막 statement 수행 후 exit() 시스템 콜을 통해
      • 프로그램에 명시적으로 적어주지 않아도 main 함수가 리턴되는 위치에 컴파일러가 넣어줌.
    • 비자발적 종료
      • 부모 프로세스가 자식 프로세스를 강제 종료시킴
        - 자식 프로세스가 한계치를 넘어서는 자원 요청
        - 자식에게 할당된 태스크가 더 이상 필요하지 않음
      • 키보드로 kill, break 등을 친 경우
      • 부모가 종료하는 경우
        - 부모 프로세스가 종료하기 전에 자식들이 먼저 종료됨

프로세스와 관련한 시스템 콜

  • fork()
    create a child (copy)
  • exec()
    overlay new image
  • wait()
    sleep until child is done
  • exit()
    frees all the resources, notify parent

프로세스 간 협력

  • 독립적 프로세스 (Independent process)

    • 프로세스는 각자의 주소 공간을 가지고 수행되므로 원칙적으로 하나의 프로세스는 다른 프로세스의 수행에 영향을 미치지 못함
    • 직접 본인것 얻어서 메모리를 만들고 CPU도 많이 얻으려고 하면서 경쟁하면서 실행하는 독립적인 프로세스
  • 협력 프로세스 (Cooperating process)

    • 프로세스 협력 메커니즘을 통해 하나의 프로세스가 다른 프로세스의 수행에 영향을 미칠 수 있음
  • 프로세스 간 협력 메커니즘 (IPC : Interprocess Communication)

    • 메시지를 전달하는 방법
      • message passing : 커널을 통해 메시지 전달
      • process A가 process B한테 메시지를 전달하고, 그 영향을 받아서 process B가 실행이 되고, 또 process B가 실행되다가 메시지를 A한테 날리면 A가 실행되고.
      • 프로세스는 원체 독립적이기 때문에, 자신의 메모리 공간만 볼 수 있고, 내가 다른 프로세스에게 메시지를 전달하는 방법도 원칙적으로는 없다.
      • 그래서 커널을 통해 메시지를 전달함.
    • 주소 공간을 공유하는 방법
      • shared memory : 서로 다른 프로세스 간에도 일부 주소 공간을 공유하게 하는 shared memory 메커니즘이 있음.
    • thread : thread는 사실상 하나의 프로세스이므로 프로세스 간 협력으로 보기는 어렵지만 동일한 process를 구성하는 thread들 간에는 주소 공간을 공유하므로 협력이 가능

message Passing

  • Message system
    • 프로세스 사이에 공유 변수(shared variable)를 일체 사용하지 않고 통신하는 시스템
    • 직접 보낼 수 없고, 운영체제 커널을 통해서 메시지를 전달
    • 메시지를 패싱하는 방법은 두가지로 나뉜다.
  1. Direct Communication

    • 통신하려는 프로세스의 이름을 명시적으로 표시
  2. Indirect Communication

    • mailbox (또는 port)를 통해 메시지를 간접 전달

Interprocess Communication

  • 물리적인 메모리이다.
  • 젤 아래부분에는 운영체제 커널
  • process A와 process B 둘 다 주소공간이 따로 있다.
  • 하지만 물리적인 메모리에 매핑할 때, 일부 영역은 공유되도록 매핑해 놓은것.
profile
항상 성장하는 개발자 최동혁입니다.

0개의 댓글