[운영체제] 9. Process Management 2

이건회·2022년 3월 17일
0

운영체제

목록 보기
8/27

  • 자식 프로세스는 부모의 모든 자원을 공유하다가, 새로운 내용을 write하면 독립적인 자원을 갖게 된다(copy-on-write).
  • 새로운 프로세스를 생성하는 시스템 콜은 fork, 새로운 프로그램을 덮어씌우는 것이 exec 시스템 콜이다.

  • fork를 사용해 사용자 프로그램이 프로세스를 만드는 코드다.
  • 코드에서 fork 함수 호출을 통해 프로세스를 만드는 시스템 콜 요청을 보낸다. 그러면 부모 프로세스가 복사된 프로세스가 생겨난다.
  • 부모 프로세스는 프로세스의 결과값이 양수, 자식은 0이다. 이를 통해 부모와 자식을 구분한다.

  • 만약 맨 위에 위와 같은 print문이 들어가면 부모 프로세스를 실행할때 print 문이 출력 되지만 자식프로세스가 실행될 때는 pc가 fork를 가리키고 있기 때문에 맨 위의 print 문이 출력되지 않는다.

  • exec 시스템 콜을 통해 프로그램이 완전히 새로운 것으로 태어난다. 위의 코드에서 fork 실행 결과로 자식 프로세스(==0)일 때 execlp 함수를 통해 exec 시스템 콜을 실행시켜 새로운 프로그램으로 덮어 씌우는 것을 볼 수 있다.

  • 만약 위 코드처럼 fork 없이 exec을 실행시킨다 해도 새로운 프로그램을 만들 수 있다.

  • 리눅스의 echo 커맨드는 뒤에 나오는 argument를 그대로 화면에 출력해준다. 따라서 다음 코드는 1 출력 뒤 3이 화면에 출력된다. 그리고 exec이 실행 됐으므로 2는 출력되지 않는다.

  • wait 시스템 콜은 프로세스를 잠들게 하는(blocked 상태로 보내는) 것이다.
  • 자식을 만든 뒤 wait을 콜하면 자식이 종료되기를 기다리면서 부모가 blocked 되고, 자식이 종료되면 부모가 ready 상태가 되어 CPU를 얻을수 있게 된다.
  • 위 그림의 코드를 보면 fork의 결과값이 0 이면 자식 프로세스 코드 실행, 0이 아닐 경우에 부모 프로세스 코드를 실행하다가 wait시스템 콜이 들어가면 잠들게 된다. 자식이 종료되면 wait 시스템 콜을 빠져나가도록 설계한다.

  • exit 시스템 콜은 프로세스를 종료시키려 할때 호출하는 시스템 콜이다.

  • 프로세스가 종료되는 경우는 프로그램이 스스로 exit 시스템 콜을 넣어 자발적 종료되는 경우가 있다.
  • 부모 프로세스가 자식프로세스를 강제로 종료시키거나 키보드 커맨드를 사용하여 종료하는, 혹은 부모 프로세스 자체가 죽기 전에 자식이 죽는 비자발적 종료가 있다.

  • 프로세스의 시스템 콜을 간단 요약하면 다음 네 가지와 같다.

  • 원칙적으로 프로세스는 독립적이다. 따라서 원래는 한 프로세스가 다른 프로세스에 영향을 미치지 못한다.
  • 그러나 경우에 따라 프로세스들이 협력을 해야지만 효율적으로 실행될 수 있다. 따라서 프로세스가 협력하는 방법, 즉 프로세스가 정보를 주고받는 방법을 IPC(Interprocess Communication), 즉 프로세스 협력 메커니즘이라 한다.
  • IPC에는 메시지 패싱과 공유 메모리 형태가 있다.

  • 메시지 패싱은 프로세스A가 커널을 통해 메시지를 전달하고, 그 영향을 받아 다른 프로세스B가 실행되고, 또 B가 필요시 A에 메세지를 전달하는 형태이다. 커널이 메신저 역할을 한다.
  • 원칙적으로 프로세스 사이에는 공유 변수가 있는것이 아니고 자신 데이터 내의 코드만 실행하는데, 따라서 메시지를 통해 소통하기 위해 운영체제 커널을 통해 메시지를 전달하는 것이다.
  • 받아볼 프로세스의 이름을 명시적으로 표시하면 다이렉트 커뮤니케이션, 메시지를 간접적으로 전달하면(누가 받아볼지를 명시하지 않음) 인다이렉트 커뮤니케이션이다(아무나 전달).

  • 원칙적으로 프로세스는 코드 데이터 스택을 독자적으로 갖지만, shared memory는 주소 공간을 공유한다.
  • shared memory를 쓸 때도 커널에 시스템 콜을 통해 shared memory를 쓸 것임을 알려야 한다.
  • 스레드는 하나의 프로세스이므로 프로세스간 협력은 아니나 스레드끼리는 주소공간을 공유해 협력이 쉽다.

  • 그림에서 shared memory는 프로세스 A와 B가 공유하는 영역이 있음을 볼 수 있다.

5. CPU 스케줄링

  • 어떤 프로그램이든 다음과 같은 path를 실행하며 진행이 된다. load store...같은 것은 CPU에서 지시를 수행하는 기계어다.
  • i/o 작업이 중간에 끼어드는 i/o burst 단계와, CPU를 연속적으로 쓰는 CPU burst 단계가 있다.
  • 모든 프로그램은 CPU burst와 i/o burst가 반복된다. 다만 프로그램에 따라 이 빈도와 길이는 다르다.

  • 다음은 CPU 버스트타임의 분포다. cpu 버스트가 짧은(i/o가 많은) 경우가 많고 i/o버스트가 적은 작업의 경우다. 이렇게 cpu를 짧게 쓰고 i/o가 많은 job을 i/o bound job이라 한다. 반대의 경우는 cpu bound job이라 한다.
  • CPU 스케줄링이 필요한 이유는 i/o 바운드는 사람과 계속 인터렉션 하므로 cpu bound job이 cpu를 잡고 놓지 않으면 i/o를 너무 오래 기다리게 된다. 따라서 사람과 인터렉션 하는 job에게 cpu를 우선적으로 주어 오래 기다리지 않도록 하기 위해 필요하다.
  • 결국 누구에게 우선적으로 cpu를 주고 언제 뺏을 것인지를 결정해야 한다.

  • i/o bound job과 cpu bound job의 차이다.

  • CPU 스케줄러는 어떤 프로세스에게 CPU를 줄 지 결정하는 운영체제 내의 코드다.(하드웨어x)

  • Dispatcher는 CPU 줄 프로세스 결정 후 그 프로세스에 CPU 제어권을 넘기는 코드다. 이 과정이 바로 문맥 교환(context switch)이다.

  • CPU 스케줄링은 프로세스의 상태 변화가 있는 경우 주로 필요하다. i/o 요청으로 프로세스가 running 에서 blocked로 바뀔 때, CPU를 쓰고 싶어 CPU를 빼앗는 경우, 또 타이머 인터럽트로 CPU를 넘겨주는 경우(running->ready) 등이다. 또 i/o 작업이 끝나고 인터럽트를 걸어 blocked가 ready로 바뀌는 경우 등이 있다. 또 어떤 프로세스가 종료되어 새로운 프로세스에 cpu를 넘기는 경우다.

  • i/o 작업이 끝나고 ready가 아닌 곧바로 CPU를 넘겨주는 경우는 해당 프로세스가 절대적 우선순위에 있는 경우다.

  • 1,4번의 예시는 cpu 자진 반납의 경우(nonpreemtive)고, 2,3번 예시는 cpu를 강제로 뺏긴 경우(preemtive)다.

profile
하마드

0개의 댓글