[운영체제] 3. 프로세스 관리 (5) - 프로세스 생성 및 시스템 콜

jyleever·2023년 2월 19일
0

운영체제

목록 보기
9/9
post-thumbnail

http://www.kocw.net/home/cview.do?lid=d1784f0ecb42285a
http://www.kocw.net/home/cview.do?lid=21cfd4db05e27901

프로세스 생성 1 (Process Creation)

부모 프로세스(Parent process)가 자식 프로세스(children process) 생성

  • 프로세스의 트리(계층 구조) 형성
  • 프로세스는 자원을 필요로 함
    • 운영체제로부터 받는다
    • 부모와 공유한다
      원칙적으로는 프로세스끼리 자원 문제로 경쟁하지만, 자식 프로세스와 부모 프로세스는 별개의 프로세스임에도 불구하고 공유할 수 있다
  • 자원의 공유
    1. 부모와 자식이 모든 자원을 공유하는 모델
    2. 일부를 공유하는 모델
    3. 전혀 공유하지 않는 모델
  • 수행(Execution)
    1. 부모와 자식은 공존하며 수행되는 모델
    2. 자식이 종료(terminate)될 때까지 부모가 기다리는(wait) 모델

프로세스 생성 2 (Process Creation)

프로세스가 생성되면 그 프로세스만의 독자적인 주소 공간(code-data-stack)이 생성된다.

  • 주소 공간 (Address Space)
    • 자식은 부모의 공간을 복사함 (binary and OS data)
      • data, stack, code 모두 복사됨. stack도 그대로 복사하기 때문에, 현재 호출된, 즉 부모가 수행한 위치에서부터 실행된다고 이해하면 됨.
    • 자식은 그 공간에 새로운 프로그램을 올림
  • 유닉스의 예
    • fork() 시스템 콜이 새로운 프로세스를 생성
      • 부모를 그대로 복사 (OS data except PID + Binary)
      • 주소 공간 할당
    • fork 다음에 이어지는 exec() 시스템 콜을 통해 새로운 프로그램을 메모리에 올림

      fork() vs exec()
      fork() : 복제 및 생성
      exec() : 완전히 새로운 프로그램으로 덮어씌우는 것

프로세스 종료(Process Termination)

컴퓨터 세계에서는 자식 프로세스가 부모 프로세스보다 먼저 종료된다

  • 프로세스가 마지막 명령을 수행한 후 운영체제에게 이를 알려줌 (exit)
    • 자식이 부모에게 종료된다는 output data를 보냄 (via wait)
    • 프로세스의 각종 자원들이 운영체제에게 반납됨
  • 부모 프로세스가 자식의 수행을 종료시킴 (abort)
    • 자식이 할당 자원의 한계치를 넘어섬
    • 자식에게 할당된 태스크가 더 이상 필요하지 않음
  • 부모가 먼저 종료(exit)하는 경우? -> 룰을 위배한 경우
    • 운영체제는 부모 프로세스가 종료하는 경우 자식이 더 이상 수행되도록 두지 않는다.
    • 단계적인 종료 (프로세스의 계층 구조의 말단에 있는 것부터 죽인다는 것)

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

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

fork() 시스템 콜

자식 프로세스 생성하는 커널 함수 호출

A process is created by the fork() system call

  • creates a new address space that is a duplicate of the caller
int main()
{	int pid;
	pid = fork();
    if (pid == 0) // this is child
    	printf("\n Hello, I am child\n");
    else if (pid > 0) // this is parent
    	print("\n Hello, I am parent\n");
}

부모 프로세스와 자식 프로세스는 원본과 복제본이기 때문에 구분할 필요가 있다.
둘 다 똑같은 부분에서부터 실행됨!

fork() 시스템 콜을 호출한 그 결과값, return value가
부모 프로세스인 경우 양수를 리턴
자식 프로세스인 경우 0을 리턴

  • parent process : pid > 0
    child process : pid = 0

보통은 자식 프로세스에게 다른 일을 시키기 때문에 pid로 구분할 필요가 있다.

exec()

부모와 자식 프로세스가 다른 프로그램을 돌리기 위해서는, 즉 새로운 프로그램을 덮어 씌우기 위해서는 exec() 시스템 콜을 이용한다.

A process can execute a differnt program by the exec() system call

  • replaces the memory image of the caller with a new program
int main()
{
	printf("\n Hello"); // printf - 1
    execlp("/bin/date", "/bin/date". (char *) 0); // execlp
    printf("\n Hello"); // printf - 2
}
  • printf-1, execlp, printf - 2 이렇게 수행되는 것이 아니라, printf - 1 수행 후 execlp 수행하여 완전히 다른 프로그램이 덮어씌워지게 됨
    따라서 printf - 2는 수행하지 않고 계속 execlp로 호출한 프로그램 속에서 수행됨

exec() 시스템 콜

A process can execute a different program by the exec() system call

  • replaces the memory image of the caller with a new program

fork() 후 exec()

int main()
{	int pid;
	pid = fork();
    if (pid == 0) // this is child
    	printf("\n Hello, I am child\n");
        execlp("/bin/date", "/bin/date". (char *) 0); // execlp

    else if (pid > 0) // this is parent
    	print("\n Hello, I am parent\n");
}
  • 부모 프로세스가 fork() 함수를 호출하여 운영체제에 자식 프로세스를 요청하면 자식 프로세스가 생성된다. 모든 시스템 안에 있는 프로세스는 부모 프로세스가 존재한다. 또한 fork()는 자기 자신의 복제 생성이다.
  • 자식 프로세스는 부모 프로세스의 문맥을 그대로 따르기 때문에 fork()가 실행된 직후부터 수행되며, 이 때 fork()의 return value는 부모 프로세스는 pid = 0, 자식의 프로세스는 pid > 0
    pid에 따라 다른 작업을 수행할 수 있도록 한다
  • 또한 exec() 는 하나의 프로세스를 완전히 다른 프로세스로 덮어씌우는 함수 (C에서는 execlp() ... exec() 호출)
    exec() 안에 수행할 프로그램과 전달할 인자를 argument 로 넣고..

wait() 시스템 콜

자식이 종료될 때까지 부모 프로세스는 block 상태

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

  • 커널은 child가 종료될 때까지 프로세스A를 sleep 시킨다 (block 상태)
  • Child process가 종료되면 커널은 프로세스 A를 깨운다 (ready 상태)

wait() 시스템 콜을 호출하는 이유?
wait()를 하지 않으면 부모와 자식 프로세스는 경쟁 상태에 놓이게 됨

exit() 시스템 콜

프로세스를 종료시키는 시스템 콜
자식 프로세스는 모든 자원을 반납하고 부모 프로세스에게 종료됨을 알림

명시적으로 작성하지 않아도 컴파일러가 마지막에 exit()를 넣어줌
프로그램 상에서 명시적으로 작성할 수도 있음

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

프로세스 간 협력

프로세스는 독립적이고 서로 간섭하지 않지만 경우에 따라서는 서로 협력이 필요할 때가 있다.

  • 독립적 프로세스 (Independent process)
    • 프로세스는 각자의 주소 공간을 가지고 수행되므로 원칙적으로 하나의 프로세스는 다른 프로세스의 수행에 영향을 미치지 못 함
  • 협력 프로세스 (Cooperating process)
    • 프로세스 협력 매커니즘을 통해 하나의 프로세스가 다른 프로세스의 수행에 영향을 미칠 수 있음
      다른 프로세스의 메모리 공간을 볼 수도 있지만 직접적인 협력은 하지 않음
  • 프로세스 간 협력 매커니즘 (IPC : Interprocess Communication)
    • 메시지를 전달하는 방법
      message passing : 커널을 통해 메시지 전달
      프로세스A가 프로세스B에게 메시지를 전달하는데, 직접 전달하는 것은 아니고 운영체제에게 시스템 콜을 하여 메시지 패싱이 이루어짐
    • 주소 공간을 공유하는 방법
      shared memory : 서로 다른 프로세스 간에도 일부 주소 공간을 공유하게 하는 shared memory
      운영체제에게 시스템 콜을 하여 shared memory가 이루어짐
      shared memory에 다른 프로세스가 써놓은 것이 공유되어있으므로 읽을 수 있음
      프로세스가 서로 신뢰할 수 있는 경우에는 공유해도 되지만, 신뢰할 수 없는 경우에는 문제가 될 수 있으므로 서로 신뢰할 수 있음을 보장해야 한다.

      thread : shared memory와는 다르다. shared memory는 다른 프로세스 간의 문제지만 쓰레드는 사실상 하나의 프로세스이므로 프로세스 간 협력으로 보기는 어렵다. 다만 동일한 process를 구성하는 thread 간에는 주소 공간을 공유하므로 협력이 가능 (쓰레드끼리.. 결국 메모리 공간이 하나니까..)

Message Passing

누가 받을지 명시하든지 메시지를 메일 박스를 통해 전달할 수 있다.
두 방법 다 직접 전달은 아님

Direct : 양자 간 누구에게 보낼지 명시
Indirect : 누구에게 보낼지 명시하지 않고 mailbox를 통해 메시지 전달

0개의 댓글