티스토리 뷰

프로세스 생성

  • 부모 프로세스(Parent process)가 자식 프로세스(children process)를 생성.
    => 복제 생성
    자식은 부모의 공간을 복사하고(binary and OS data), 그 공간에 새로운 프로그램을 올림
    -> 부모의 주소 공간, 운영체제의 자원을 다 복사해놓고 새로운 프로그램을 덮어씌움.

    유닉스의 예)
    fork() 시스템 콜이 새로운 프로세스를 생성
    -> 부모를 그대로 복사, 주소 공간 할당
    fork 다음에 이어지는 exec() 시스템 콜을 통해 새로운 프로그램을 메모리에 올림

    복제하지않고 덮어씌울수도 있으며, 운영체제를 통해서만 프로세스 생성 가능.

  • 하나의 프로세스가 여러 개의 자식 프로세스를 생성할 수 있음
    -> 트리(계층 구조) 형성

  • 프로세스는 자원을 필요로 함
    -> 운영체제로부터 받음
    -> 원칙적으로는 부모가 자식을 낳으면 그때부터는 별도의 프로세스이기 때문에 서로 경쟁하는 사이이므로 자원을 공유하지 않음. COW의 경우 부모 것을 그대로 공유할 수도 있음.
    *COW ( Copy-On-Write): 자식 프로세스가 부모의 것을 그대로 공유하다가 수정이 일어났을 때 copy를 진행.

  • 자원의 공유
    - 부모와 자식이 모든 자원을 공유하는 모델
    - 일부를 공유하는 모델
    - 전혀 공유하지 않는 모델 -> 일반적인 경우

  • 수행(Execution)
    - 부모와 자식은 공존하며 수행되는 모델
    - 자식이 종료(terminate)될 떄까지 부모가 기다리는(wait)모델

프로세스 종료

  • 프로세스가 마지막 명령을 수행한 후 운영체제에게 이를 알려줌 (exit)
    자식이 부모에게 output data를 보냄 (via wait)
    프로세스의 각종 자원들이 운영체제에게 반납됨.

  • 부모 프로세스가 자식의 수행을 종료시킴 (abort)
    자식이 할당 자원의 한계치를 넘어선 경우
    자식에게 할당된 태스크가 더 이상 필요하지 않은 경우
    부모가 종료(exit)하는 경우
    - 운영체제는 부모 프로세스가 종료하는 경우 자식이 더 이상 수행되도록 두지 않음.
    - 단계적인 종료 => 부모 프로세스가 가장 마지막에 죽음.

fork () 시스템 콜

 

fork를 만나면 자식 프로세스가 하나 생김.

자식 프로세스는 main함수의 시작 부분부터 시작하는 것이 아니라 fork를 실행한 이후부터 수행

-> 부모 프로세스의 context를 복제하는데 PC도 복제되기 때문에 시작 부분부터 실행되는 것이 아님!!

 

여기서 발생할 수 있는 문제가 있음.

-> 복사된 자식 프로세스가 부모 프로세스를 복제본 취급할 수도 있음.

-> fork를 하게되면 부모랑 똑같은 것이 만들어지므로 모든 프로그램들은 같은 제어 흐름을 따라갈 것 같음.

 

위와 같은 문제 때문에, 복제할 때 자식과 부모를 구분시킴.

-> fork 함수의 return value가 다름. 부모는 결과값이 양수, 자식은 0

 

exec() 시스템 콜

 

완전히 새로운 프로세스로 태어나게 해줌.

fork를 지난 후 자식 프로세스가 생성되고 printf 실행 후 자식은 date라는 새로운 프로그램으로 덮어쓰이게 됨.

 

exec() 이 자식을 만들어서 써야하는 것은 아님. fork를 빼고 사용한다면 현재 실행중인 프로그램을 잊고 date라는 새로운 프로그램을 덮어써서 date라는 프로그램의 main 함수 시작부터 실행함.

 

wait() 시스템 콜

 

프로세스를 blocked 상태로 만듦.

프로세스 A가 wait() 시스템 콜을 호출하면

-> 커널은 child가 종료될 때까지 프로세스 A를 sleep시킴. (block상태)

-> Child process가 종료되면 커널은 프로세스 A를 깨움. (ready상태)

 

위 그림의 모델은 부모와 자식이 병렬적으로 실행되는 경우가 아닌 부모가 자식 프로세스를 낳아놓고 자식이 일을 다 수행하고 종료될 때까지 기다리는 모델임.

 

exit() 시스템 콜

 

프로세스를 종료시킬 때 호출하는 시스템 콜

  • 자발적 종료
    마지막 statement 수행 후 exit() 시스템콜을 통해 프로그램에 명시적으로 적어주지 않아도 main 함수가 리턴되는 위치에 컴파일러가 넣어줌.

  • 비자발적 종료 (프로그램 본인은 실행중인데 밖에서 죽임)
    부모 프로세스가 자식 프로세스를 강제 종료시킴.
    -> 자식 프로세스가 한계치를 넘어서는 자원 요청
    -> 자식에게 할당된 태스크가 더 이상 필요하지 않음.

    키보드로 kill, break 등을 친 경우

    부모가 종료하는 경우
    -> 부모 프로세스가 종료하기 전에 자식들이 먼저 종료됨.

프로세스 관련한 시스템 콜

  • fork(): 자식 생성(copy)
  • exec(): 새로운 프로그램으로 덮어씌움.
  • wait(): 자식이 일을 끝낼 때까지 sleep
  • exit(): 모든 자원을 놓은 뒤, 부모에게 알림.

프로세스 간 협력

원칙적으로는 독립적임.

  • 독립적 프로세스 (Independent process)
    프로세스는 각자의 주소 공간을 가지고 수행되므로 원칙적으로 하나의 프로세스는 다른 프로세스의 수행에 영향을 미치지 못함. (부모가 자식을 죽이는 경우는 있음)
  • 협력 프로세스 (Cooperating process)
    프로세스 협력 매커니즘을 통해 하나의 프로세스가 다른 프로세스의 수행에 영향을 미칠 수 있음

  • 프로세스 간 협력 메커니즘 (IPC: Interprocess Communication)

    1. 메세지를 전달하는 방법
    -> message passing: 커널을 통해 메세지 전달
    프로세스는 자기 주소공간만 볼 수 있고 다른 프로세스한테 메세지를 전달할 수 있는 방법도 원칙적으로는 없으므로 커널을 통해 메세지를 전달함.

    2. 주소 공간을 공유하는 방법
    -> shared memory: 서로 다른 프로세스 간에도 일부 주소 공간을 공유하게 하는 shared memory 메커니즘이 있음.

    *thread
    -> thread는 사실상 하나의 프로세스이므로 프로세스 간 협력으로 보기는 어렵지만 동일한 process를 구성하는 thread들 간에는 주소 공간을 공유하므로 협력 가능

    shared memory도 프로세스끼리 바로 직접 주소 공간을 공유할 수 있는 것이 아닌 커널한테 shared memory를 쓴다는 시스템 콜을 해서 맵핑을 해놓고 사용함.


    Message Passing
    -> 프로세스 사이에 공유 변수(shared variable)를 일체 사용하지 않고 통신하는 시스템

    - Direct Communication: 통신하려는 프로세스의 이름을 명시적으로 표시
    - Indirect Communication: mailbox (또는 port)를 통해 메세지를 간접 전달

결국은 운영체제 커널을 통해 전달해야되는 것은 같음. 사용자 프로세스끼린 전달 불가능.

 

댓글
최근에 올라온 글
Total
Today
Yesterday