feldblume5263 / TIL

Today I Learned
0 stars 0 forks source link

(220822)[개인 공부] 운영체제 4강 #8

Closed feldblume5263 closed 2 years ago

feldblume5263 commented 2 years ago

반효경 교수님 운영체제 4강 약 1시간 30분 강의이기 때문에 2시간 이상 소요 예정

feldblume5263 commented 2 years ago

프로세스 생성

부모 프로세스가 자식 프로세스를 생성한다.
복제하는 방식으로 생성

fork() // 시스템 콜이 새로운 프로세스를 생성
// - 부모를 그대로 복사(OS data except PID + binary)
// - 주소 공간 할당

exec() // 시스템 콜을 통해 새로운 프로그램을 메모리에 올림

exit() // 프로세스가 마지막 명령을 수행한 후 운영체제에게 이를 알려줌
// - 자식이 부모에게 output data를 보냄 (via wait) <- 무조건 자식이 부모보다 먼저 종료되어야 함
// - 프로세스의 각종 자원들이 운영체제에게 반납됨

abort() // 부모 프로세스가 자식의 수행을 종료시킴
// - 자식이 할당 자원의 한계치를 넘어섬
// - 자식에게 할당된 테스크가 더 필요하지 않음
// - 부모가 exit 하는 경우 -> 운영체제는 부모 프로세스가 종료하는 경우 자식이 더 이상 수행되도록 두지 않는다, 단계적인 종료


원칙적으로 서로 자원을 공유하지 않는다.
자식 프로세스가 부모 프로세스를 그대로 copy하기 때문에 메모리에 두개의 복사본이 올라간다. 즉 메모리의 낭비가 일어난다.
리눅스 같은 효율적인 운영체제는 copy하지 않고 자식이 부모의 기존 내용을 공유한다.
그리고 어느정도 일을 하면서 각자의 길을 가게 되면 그제서야 부모에 공유하던 메모리공간 일부를 copy해서 가지게 된다. COW기법(copy on write)
즉, 일단 공유하다가 write가 일어나면 그 부분을 copy하여 자식 프로세스에서 관리하는 것이다.

프로세스가 실행 될 때 부모와 자식이 공존하면서 수행되는 모델이 있고
자식이 종료될 때 까지 부모가 기다리는 모델이 있다.

fork() 시스템콜

다음과 같이 사용된다.

int main()
{
    int pid;
    pid = fork(); // 자식프로세스는 fork를 실행한 이후 시점부터 실행되게 된다. -> 부모의 PC가 여기를 가르키고 있기 떄문
    if (pid == 0) // 자식 프로세스
        printf("I'm child\n");
    else if (pid > 0) // 부모 프로세스
        printf("I'm parent\n");
}


exec() 시스템콜

하지만 위와 같은 방식이면 같은 코드를 가진 프로세스들만 존재하게 된다.
그래서 존재하는 시스템콜이 exec() 시스템콜이다.
어떤 프로세스가 완전히 새롭게 태어날 수 있게 하는 역할을 한다.

int main()
{
    int pid;
    pid = fork();
    if (pid == 0)
    {
        printf("I'm child\n");
        execlp("/bin/date", "/bin/date", (char *)0); // 자식은 date라는 프로그램으로 덮어 씌워진다. 한번 exec 하면 되돌아올 수 없다.
    }
    else if (pid > 0)
        printf("I'm parent\n");
}

wait() 시스템콜

wait 시스템콜은 프로세스를 child가 종료될때 까지 Block 상태로 잠들게하는 시스템콜 함수이다.

int main()
{
    int childPID;

    //...

    childPID = fork()
    if (childPID == 0)
    {
        //...
    }
    else
    {
        wait();
    }

    // ... <-  이 코드는 자식이 종료된 후에, 즉 wait가 끝난 후에 실행된다.
}

exit() 시스템콜

프로세스를 종료시킨다.

자발적 종료

비자발적 종료

프로세스 간 협력

독립적 프로세스

협력 프로세스

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

Message Passing

프로세스 간에 공유 변수가 없기 때문에 다른 프로세스에게 정보 전달할 때는 메세지를 보낸다. 직접 보낼 수는 없고 OS 커널을 이용해야 한다.

Shared Memory

일부 메모리 주소 공간을 공유하는 것이 shared Memory 매커니즘이다.
원칙적으로 프로세스는 코드, 데이터, 스택 등 독자적인 주소 공간을 가지고 있기 때문에, 자기 주소 공간만 접근할 수 있는데,
shared Memory는 일부 주소공간을 두 프로세스가 공유할 수 있게 하는 것이다.

스크린샷 2022-08-23 오전 11 26 32

thread

스레드는 하나의 프로세스 안에 CPU 수행 단위가 여러개 있는 것이기 떄문에, 프로세스 간의 공유는 아니다
thread 간의 자원 공유는 매우 쉽다.
주소 공간이 애초에 공유되어있기 때문

feldblume5263 commented 2 years ago

프로그램은 CPU burst 와 I/O burst의 연속이다.

스크린샷 2022-08-23 오전 11 44 20

I/O burst가 빈번하게 일어나서 CPU burst가 짧은 경우를 I/O bound job이라고 부르고
CPU burst가 긴 경우를 CPU bound job이라고 부른다.

사람하고 interaction을 더 많이 하는 프로그램(I/O burst)에 CPU를 더 주는게 효율적이다.

CPU Scheduler & Dispatcher

CPU Scheduler

CPU를 누구에게 줄 지 결정하는 운영체제의 코드

Dispatcher

CPU를 스케줄러를 통해 누구에게 줄지 결정했으면, 그 프로세스에게 CPU를 넘겨주는 역할을 하는 코드
이 과정을 context switch라고 한다.

CPU 스케줄링이 필요한 경우

  1. Running -> Blocked

    • CPU를 프로세스를 잡고 있다가 그 프로세스가 I/O 작업처럼 오래 걸리는 작업을 하러 가는 경우
  2. Running -> Ready

    • 프로세스는 CPU를 계속 쓰고 싶지만 할당시간이 만료되면 빼앗아와야 한다.
  3. Blocked -> Ready

    • I/O 요청한 작업이 끝났으면 device controller가 interrupt를 걸어서 프로세스를 Ready로 바꿔준다.
  4. Terminate

    • 프로세스가 종료되어 더 이상 할일 없을 때, CPU가 필요 없을 때