일반적으로 작업관리자를 켜봤다면 모든 단위들이 프로그램이 아닌 프로세스라는 것을 알 수 있다. 프로그램과 프로세스의 차이는 무엇인지 프로세스에 대해서 자세히 알아보도록 하자~

Program VS Process

일단 프로그램은 디스크에 있는 실행파일을 말한다. 이 파일을 실행시키면 메모리에 해당 파일을 올려서 실제 실행이 된다. 따라서 프로그램은 실행을 하기 위한 실행파일이라고 볼 수 있다.

반면 프로세스는 프로그램을 실행했을 때 실행되는 인스턴스이다. 실행과 스케쥴링의 가장 기본적인 단위이며 각 프로세스는 고유의 ID 값을 가지고 있다.

Process Address Space

메모리의 주소 공간은 크게 4가지로 나눌 수 있다.

  • Code Text segment. 프로그램의 기계어 명령어가 들어가있다. 실제 작성한 코드들이 들어가 있으며 순차적으로 명령어를 실행하게된다.
  • Data Data segment. 프로그램이 실행되는 동안 항상 메모리를 차지하고 있을 수 있는 영역이다. 따라서 전역 변수 등 메모리에 계속해서 남아있어야하는 변수들이 존재하는 영역이다. static data 인 만큼 java 에서 static 변수들이 들어간다고 생각할 수 있다.
  • Heap Dynamic allocated memory. 동적으로 사용되는 메모리 영역이다. new, alloc 을 통해 동적으로 할당되었다가 해제하면 없어지는 영역이다.
  • Stack 지역 변수들이 저장되는 영역이다. 함수 내부에서 정의된 변수들이 저장되었다가 함수가 끝나면 사라지는 영역이다.

image

Process State

프로세스의 실행 상태이다. 총 5개의 상태가 존재한다. 프로그램이 처음 실행되어 프로세스가 만들어지면 new 상태이다. 이후에 실행될 준비가 되면 ready 상태로 이동한다. 여러 ready 상태의 프로세스 중에서 지금 실행될 프로세스를 스케쥴링을 통해 고르게되면 해당 프로세스만 running 상태로 변경된다. 해당 프로세스가 할 일을 모두 마치고 종료되면 terminated 상태가 되는 것이고, 실행 중에 인터럽트가 걸리면 다시 ready 상태에서 다음 실행을 기다린다. 이때 I/O 입력을 기다린 후에 다음 실행이 가능한 경우 등에서는 해당 이벤트를 기다리기 위해 wait 상태가 된다. 이후 기다리던 이벤트가 발생하게되면 다시 실행가능한 상태인 ready 상태가 된다.

image

Process Control Block

프로세스의 정보가 담긴 블럭이다. 프로세스의 상태와 고유 번호, 레지스터에 저장된 값 등 프로세스가 실행되면서 필요한 모든 정보들이 담겨있다. 따라서 프로세스가 running 중에 멈추더라도 PCB 를 보고 하던 작업을 이어나갈 수 있는 것이다.

image

Context Switch

실행되는 프로세스가 바뀌는 것을 context switch 라 한다. 프로세스가 인터럽트가 발생하면 OS 가 실행되게 되고 현재 수행 중인 프로세스의 상태를 해당 PCB 에 저장하게 된다. 그리고 다음 실행될 프로세스의 PCB 를 불러오면서 dispatch 해서 프로세스를 running 한다. 아래 그림을 보면 P0 -> P1 -> P0 순서대로 실행되는 것을 나타낸다. 프로세스가 변경될 때 각 PCB 가 저장되고 불러와진 후에 다음 프로세스가 실행되는 것을 확인할 수 있다. Idle process 는 No operation 이라는 무한 루프를 돈다. State 는 항상 ready 상태이기 때문에 모든 프로세스들이 waiting 상태일 때 idle process 가 실행된다. 아래 그림에서도 PCB 를 불러오기 전까지는 어떤 프로세스도 실행할 수 없기 때문에 idle process 가 실행되고 있다.

image

Schedulers

앞서 말했던 스케쥴링에 대한 이야기이다. 결국 여러 프로세스 중에서 어떤 순서대로 실행시킬지에 대한 이야기이며 총 세 가지 스케쥴러가 존재한다

  1. Long-term schedular 실행시킬 프로그램이 현재 파일 시스템에 있을 때 어떤 프로그램을 메인 메모리에 올리고 어떤 프로그램을 ready queue 에 올릴 지 결정하는 것이다.
  2. Short-term schedular 실행 요청이 10개가 들어왔을 때 현재 실행 가능한 요청이 5개라면 어떤 5개의 요청을 먼저 메인 메모리에 올릴 것인 지 결정하는 것이다. 또한 메인 메모리에 올린 5개의 요청 중에서도 어떤 요청을 바로 CPU 에 올려 실행할 것인지 결정한다.
  3. Medium-term schedular 메인 메모리에서 5개의 요청을 버거워해서 하나의 요청을 다시 파일 시스템으로 내려야한다면 어떤 요청을 내릴 것인지 결정하는 것이다.

image

System Call

시스템 콜은 커널 영역의 기능을 사용자 모드가 사용 가능하게 하기 위한 시스템 함수이다. 프로세스에 관한 시스템 콜만 간단하게 알아보자.

  • fork() 리눅스에서 프로세스 생성을 담당하며 fork() 는 자신과 똑같은 자식 프로세스를 생성하는 시스템콜이다. 모든 프로세스는 각자의 PCB 를 가져야하기 때문에 프로세스를 생성하면 역시 새로운 PCB 를 생성한다. 이때 자신의 PCB 의 내용과 동일한 PCB 를 생성하기 때문에 부모 프로세스와 자식 프로세스는 완전히 동일한 작업 상태를 가진다. fork 의 return value 가 부모와 자식 프로세스가 다르기 때문에 if 문을 사용해서 하나의 프로그램 내에서 각자 다른 실행을 하도록 만들 수 있다. 또한 이후에 작성할 TCP 에서 커넥션을 생성한 후 fork 를 하면 자식 프로세스도 커넥션이 되어있는 상태이기 때문에 부모 프로세스에서만 커넥션을 끊어주면 부모는 계속해서 새로운 요청을 받을 수 있고 요청을 받으면 새로운 자식 프로세스를 통해 여러 TCP 커넥션을 유지할 수 있다.
  • exec() 프로세스를 실행하는 시스템콜이다. 현재 실행되던 프로세스를 없애버리고 그 자리에 새로운 프로세스를 실행한다. 새로운 프로그램을 처음 실행시킨다 하면 프로세스가 새롭게 생성이 되어야한다. 이때 새로운 프로세스를 만드는 작업이라고 볼 수도 있다. 리눅스에서는 fork 를 통해 자식 프로세스를 만들게되고 자식 프로세스에서 exec 를 실행시킨다면 자식 프로세스가 완전히 다른 프로세스로 바뀐다.

    리눅스는 fork 때문에 모든 프로세스들이 부모-자식 관계를 가지고 있다. 시스템 콜에 대해서는 이후 시스템 프로그래밍으로 자세하게 설명하도록 하겠다.

Inter-Process Communication

프로세스간 데이터를 주고 받기 위한 방법이다. 서로 다른 프로세스이므로 새로운 공간을 할당해서 데이터를 주고 받아야하는데 이를 메모리 영역을 사용할 것인지, 커널영역을 사용할 것인지에 따라 다르다.

  1. Message passing 커널에 message queue 를 만들어 놓는다. 데이터를 보내야하면 queue 에 데이터를 쓰면 운영체제가 다른 프로세스에게 데이터를 읽어가라고 알려준다. 데이터 동기화를 커널이 해줄 수 있다.
  2. Shared memory 두 개의 프로세스가 동시에 하나의 메모리에 접근할 수 있는 방식. 프로세스에서 바로 접근할 수 있기 때문에 성능이 더 좋다. 하지만 A 가 데이터를 쓰고 난 후에 B 가 읽어야하는데, A 가 데이터를 썼는 지 알 수 없기 때문에 별도의 동기가 필요하다.

image

업데이트:

댓글남기기