프로세스 관리
프로세스란 실행 중인 프로그램을 뜻한다.
디스크에 실행파일 형태로 존재하던 프로그램이 메모리에 올라가서 실행되기 시작하면 비로소 생명력을 갖는 프로세스가 된다.
프로세스는 CPU를 획득해 자신의 코드를 수행하기도 하고, 때로는 CPU를 반환하고 입출력 작업을 수행하기도 한다.
그러다 자신의 임무를 다 수행하면 종료되어 사라진다.
프로세스가 시작해서 종료할 때 까지 CPU에서 명령을 한꺼번에 수행하면 좋겠지만, 여러 프로세스가 함께 수행되는 시분할 시스템 환경에서는 타이머 인터럽트에 의해 짧은 시간 동안 CPU를 사용한 후 빼앗겼다가 추후에 다시 CPU를 획득하는 식으로 CPU 관리가 이루어진다. 따라서, 수행을 재개하는 시점에는 이전에 어디까지 명령을 수행했는지 정확한 상태를 재현할 필요가 있다.
정확한 재현을 위해 필요한 정보가 바로 프로세스 문맥이다.
즉 프로세스의 문맥은 그 프로세스의 주소 공간(코드, 데이터, 스택 상태)을 비롯해 레지스터에 어떤 값을 가지고 있었는지와, 시스템 콜 등을 통해 커널에서 수행한 일의 상태, 그 프로세스에 관해 커널이 관리하고 있는 각종 정보 등을 포함하게 된다.
프로세스의 문맥은 크게
- 하드웨어 문맥
- 프로세스의 주소 공간
- 커널상의 문맥
으로 나눌 수가 있다.
하드웨어 문맥은 CPU의 수행 상태를 나타내는 것으로 프로그램 카운터 값과 각종 레지스터에 저장하고 있는 값들을 의미한다.
프로세스는 코드, 데이터, 스택으로 구성되는 자기 자신만의 독자적인 주소 공간을 가지고 있다.
프로그램이 수행되어 프로세스가 되면 운영체제는 프로세스를 관리하기 위한 자료구조를 유지하고, PCB와 커널스택이 이에 해당된다.
프로세스의 상태
- 실행: 프로세스가 CPU를 보유하고, 기계어 명령을 실행하고 있는 상태
- 준비: CPU만 보유하면 당장 명령을 실행할 수 있지만, CPU를 할당받지 못한 상태
- 봉쇄: CPU를 할당받더라도 당장 명령을 실행할 수 없는 상태
- 시작: 프로세스가 시작되어 그 프로세스를 위한 각종 자료구조는 생성되었지만 아직 메모리 획득을 승인받지 못한 상태
- 완료: 프로세스가 종료되었으나 운영체제가 그 프로세스와 관련된 자료구조를 완전히 정리하지 못한 상태
프로세스가 실행되는 도중에 타이머 인터럽트가 일어나면 타이머 인터럽트 처리루틴으로가서 수행 중이던 프로세스의 문맥을 저장하고 준비 상태에 있는 프로세스 중에서 새롭게 CPU의 제어권을 부여할 프로세스를 선택한다. 그러면 수행 중이던 프로세스는 준비 상태로 변하고 새롭게 CPU를 할당받은 프로세스가 실행 상태가 된다. 이렇게 수행 중이던 프로세스의 문맥 저장하고 새로운 프로세스의 문맥을 세팅하는 과정을 문맥교환이라고 한다.
실행 상태에 있던 프로세스가 입출력 요청 등으로 봉쇄 상태로 바뀌는 경우도 있는데, 이때 준비 상태에 있던 프로세스들 중에서 CPU를 할당받을 프로세스를 선택한 후 실제로 CPU의 제어권을 넘겨받는 과정을 CPU 디스패치 라고한다.
ex) 프로세스 수행 도중 디스크에서 파일의 내용을 읽어와야 하는 명령이 내려졌다고 하자. 해당 작업은 시간 소요가 크기 때문에 작업이 완료되기 전까지 봉쇄상태로 바뀌게 된다. 그리고 CPU를 적절한 프로세스를 하나 선정해 할당하게 된다. 디스크 작업이 다 끝나면 디스크 컨트롤러가 인터럽트를 발생시켜 입출력이 완료되었다는 것을 알린다. 그러면 해당 인터럽트를 확인하고 그에 대응하는 루틴을 수행한다. 이 루틴이 진행되는 동안 CPU에서 수행되던 프로세스의 상태는 사용자모드 실행 상태에서 커널모드 실행 상태로 바뀐다. 인터럽트 처리가 끝나면 이전에 수행되던 프로세스에게 CPU를 다시 할당해 그 프로세스의 직전 수행 시점 이후의 코드가 실행된다. 경우에 따라서는 인터럽트 당한 프로세스가 아닌 더 우선순위가 높은 프로세스한테 CPU 제어권을 이양시킬 수도 있다.
프로세스 제어블록
프로세스 제어블록(PCB)이란 운영체제가 시스템 내의 프로세스들을 관리하기 위해 프로세스마다 유지하는 정보들을 담는 커널 내의 자료구조를 뜻한다. PCB는 다음과 같은 요소들로 구성되어 있다.
- 프로세스의 상태: CPU를 할당해도 되는지 여부를 결정하기 위해 필요하다.
- 프로그램 카운터 값: 다음에 수행할 명령의 위치를 가리킨다.
- CPU 레지스터 값: CPU 연산을 위해 현 시점에 레지스터에 어떤 값을 저장하고 있는 지를 나타낸다.
- CPU 스케줄링 정보: 프로세스의 CPU 스케줄링을 위해 필요한 정보
- 메모리 관리 정보: 프로세스의 메모리 할당을 위해 필요한 정보
- 자원 사용 정보: 사용자에게 자원 사용 요금을 계산해 청구하는 등의 용도
- 입출력 상태 정보: 프로세스가 오픈한 파일 정보 등 프로세스의 입출력 관련 상태 정보
문맥교환
사용자 프로세스로부터 다른 사용자 프로세스로 CPU의 제어권이 이양되는 과정이다.
수행 중이던 프로세스는 준비상태로 바뀌고 프로세스의 문맥을 자신의 PCB에 저장하고, CPU를 할당받을 프로세스는 PCB로부터 자신의 문맥을 복원시키는 과정을 한다. 타이머 인터럽트 외에도 프로세스가 입출력 요청이나 다른 조건을 충족하지 못해 CPU가 봉쇄 상태가 되는 경우에도 발생할 수 있다.
인터럽트 또는 시스템 콜이 발생하면 CPU의 제어권이 운영체제로 넘어와서 원래 실행 중이던 프로세스의 업무를 잠시 멈추고 운영체제 커널의 코드가 실행 된다. 이 때 CPU의 실행 위치와 프로세스의 문맥 중 일부를 PCB에 저장하게 되지만 이러한 과정을 문맥교환이라고 하지 않는다. 이는 프로세스의 실행모드만이 사용자 모드에서 커널모드로 바뀔 뿐이고 곧 사용자모드로 복귀된다.
타이머 인터럽트 또는 입출력 요청 시스템 콜의 경우 사용자 모드에서 커널모드로 바뀌고 문맥교환이 일어나고 사용자 모드로 복귀한다.
단순한 모드 변경에 비해 문맥 교환에는 훨씬 많은 오버헤드가 뒤따르므로, 타이머에 CPU 할당시간을 작게 세팅하면 오버헤드가 커지고 그렇다고 너무 크면 시분할 시스템의 의미가 퇴색 되게된다.
프로세스를 스케줄링하기 위한 큐
준비 상태에 있는 프로세스들을 줄 세우기 위해 준비 큐를 둔다. 줄 세우는 방법은 CPU 스케줄링에 따라 달라진다.
CPU를 위한 준비 큐 외에도 여러 장치 큐들이 있다.
디스크 입출력 서비스를 위한 디스크 입출력 큐나 키보드 입출력 큐 등이 있다. 해당 입출력이 완료되면 디스크 컨트롤러가 인터럽트를 발생시키게 되고, 해당 인터럽트 처리루틴에 의해 CPU를 기다리는 준비 큐에 줄서게 된다.
이는 공유 데이터에 대한 접근 권환에도 마찬가지이다. 일관성 훼손을 방지하기 위해 공유 데이터는 매 시점 하나의 프로세스만이 접근하게끔 한다.
스케줄러
스케줄러란 어떤 프로세스에게 자원을 할당할지를 결정하는 운영체제 커널의 코드를 지칭한다.
장기 스케줄러는 작업 스케줄러라고 부르며, 어떤 프로세스를 준비 큐에 진입시킬지 결정하는 역할을 한다. CPU에서 실행되기 위해서는 프로세스가 메모리를 보유해야 하므로 장기 스케줄러는 프로세스에게 메모리를 할당하는 문제에 관여하게 된다.
단기 스케줄러는 CPU 스케줄러라고도 하며, 준비 상태의 프로세스 중에서 어떤 프로세스를 다음번에 실행 상태로 만들 것인지 결정한다. 타이머 인터럽트가 발생하면 단기 스케줄러가 호출된다.
단기 스케줄러는 수행 속도가 충분히 빨라야 되고, 장기는 느린 것이 허용된다. 장기는 메모리에 동시에 올라가 있는 프로세스의 수를 조절하는 역할을 한다. 이는 시작 상태의 프로세스에게 메모리 할당을 승인할지 여부를 장기 스케줄러가 결정하기 때문이다.
현대의 시분할 시스템용 운영체제에서는 프로세스가 시작 상태가 되면 장기 스케줄러 없이 곧바로 프로세스에 메모리를 할당해 준비 큐에 넣어주게 된다. 오히려 중기 스케줄러를 두는 경우가 많다. 이는 너무 많은 프로세스에게 메모리를 할당해 시스템의 성능이 저하되는 경우 메모리에 적재된 프로세스의 수를 동적으로 조절하기 위해 추가된 스케줄러이다. 메모리에 올라와 있는 프로세스 중 일부를 선정해 이들로부터 메모리를 통째로 빼앗아 그 내용을 디스크의 스왑 영역에 저장하는 것을 스왑 아웃이라고 부른다.스왑아웃의 0순위는 봉쇄 상태에 있는 프로세스 들이다. 이로 인해 중지라는 상태가 하나 더 생긴다. 스왑 아웃된것이 중지상태인데, 중지 내에서도 입출력 등 작업완료가 되면 중지준비 상태, 아니면 중지봉쇄 상태라고 부른다. 전자는 준비 상태와 스왑 아웃/인이 되고 후자는 봉쇄상태와 스왑 아웃/인이 된다.
프로세스의 생성
운영체제가 프로세스 전부를 생성하는 것이 아니라 최초의 프로세스만 직접 생성하고 나머지는 이미 존재하는 프로세스가 다른 프로세스를 복제 생성하게 된다. 프로세스의 세계에서는 자식이 먼저 죽고, 이에 대한 처리는 자식을 생성했던 부모 프로세스가 담당한다.
생성된 프로세스는 작업 수행을 위해 자원이 필요한데, 운영체제에게 따로 할당 받을 수도 있고, 부모 프로세스와 자원 공유할 수도 있고 자식이 종료될 때 까지 부모가 기다리는 경우도 있다.
운영체제는 자식 프로세스의 생성을 위해 fork() 시스템 콜을 제공한다. 프로세스가 fork() 시스템콜을 하게되면 CPU의 제어권이 커널로 넘어가게 되고, 커널은 fork()를 호출한 프로세스를 복제해 자식 프로세스를 생성하게 된다. 모든 문맥이 동일하게 복제되기 때문에 부모 프로세스가 현재 수행한 시점부터 수행하게 된다(프로그램 카운터 지점). 다만 운영체제에서 관리하기 위해 사용하는 프로세스 식별자는 다르다. 하지만 다른 작업을 시킬 수도 있기 때문에 exec()라는 시스템 콜을 지원한다. 이는 프로세스가 지금까지 수행했던 상태를 잊고 그 주소 공간을 완전히 새로운 프로그램으로 덮어씌운 후 첫 부분부터 다시 실행을 시작하도록 하는 콜이다. wait() 함수도 있는데 이는 자식 프로세스가 종료되기를 기다리며 부모 프로세스가 봉쇄 상태에 머무르게 한다. 자식 프로세스가 종료되면 부모를 준비 상태로 변경한다. 이러면 부모와 자식간의 동기화가 가능해진다. 프로세스는 명령을 모두 수행한 후, 마치는 코드에 exit() 시스템 콜을 넣게 되어있다. 즉 프로세스는 시스템 콜을 통해 운영체제에게 자신이 종료됨을 알린다.
프로세스 간의 협력
프로세스는 각자 자신만의 독립적인 주소 공간을 가지고 수행되며 프로세스가 다른 프로세스의 주소 공간을 참조하는 것은 허용되지 않는다. 경우에 따라서 프로세스들이 협력할 때 처리 속도가 향상되는 등 효과를 발휘할 수가 있다. 따라서 운영체제는 프로세스 간의 협력 메커니즘을 제공해 하나의 프로세스가 다른 프로세스의 수행에 영향을 미칠 수 있게 한다. 대표적인 메커니즘으로 IPC(Inter-Process Communication)가 있다.
IPC란 하나의 컴퓨터 안에서 실행 중인 서로 다른 프로세스 간에 발생하는 통신을 말한다. 이러한 통신에서는 데이터 불일치 문제 등으로 인해 의사소통과 동기화를 보장해주어야 하고, IPC는 프로세스들 간의 통신과 동기화를 이루기 위한 메커니즘을 의미한다. 대표적인 방법으로는 메세지 전달 방식과 공유메모리 방식이 있다. 이 두 방식의 차이는 프로세스 사이에 공유 데이터를 사용하는가, 그렇지 않는가에 있다.
메세지 전달 방식은 공유 데이터 없이 커널에 의해 send 와 receive라는 두 가지 연산을 제공받아 메세지 통신을 하게된다. 프로세스는 전달할 메세지를 운영체제에게 시스템 콜 방식으로 요청해 전달한다. 악의적인 것을 막기 위해 운영체제는 커널을 통해서만 가능하도록 한다. 통신을 하려는 두 프로세스는 커뮤니케이션 링크를 생성한 후 send와 receive를 이용하게 된다.
직접 통신은 통신하려는 프로세스의 이름을 명시적으로 표기한다.
간접통신은 메세지를 메일박스 또는 포트로부터 전달받는다.
공유메모리 방식은 프로세스들이 주소 공간의 일부를 공유해서 전달한다. 원칙적으로는 서로 다른 프로세스는 독립적인 주소 공간을 가지고 자신의 주소 공간에 특정한 내용을 쓸 경우 자신만 볼 수 있지만, 운영체제가 공유 메모리를 사용하는 시스템 콜을 지원해 공간 중 일부를 공유할 수가 있다. 공유 메모리 영역은 여러 프로세스가 읽고 쓰는 것이 가능하다. 일관성 문제가 유발될 수 있고, 커널이 책임지지 않기 때문에 프로세스들끼리 직접 공유메모리 접근에 대한 동기화 문제를 책임져야 한다.
'공부 기록들' 카테고리의 다른 글
가상 메모리 (0) | 2020.10.25 |
---|---|
메모리 관리 (0) | 2020.10.24 |
CPU 스케줄링 (0) | 2020.10.23 |
앞으로 (0) | 2020.06.26 |
2020.06.21-22 JPA(5) (0) | 2020.06.21 |