1. PCB (Process Control Block)
운영체제가 각 프로세스를 관리하기 위해 프로세스당 유지하는 정보를 말합니다.
PCB를 구성하는 것은 사진과 같이 4가지 정도로 나눌 수 있습니다.
(1) OS가 관리상 사용하는 정보
- Process state, Process ID
- Scheduling information
프로세스의 상태(Ready, Blocked, Running 등), 프로세스를 식별하기 위한 ID, 그리고 프로세스에서 CPU를 주기 위한 스케줄링 정보 등이 있습니다. 앞선 포스팅에서 CPU에 queue형태로 프로세스가 대기하는 것을 볼 수 있었는데, 정확히는 먼저 온 순서가 아닌 우선순위가 높은 순서로 실행이 됩니다.
(2) CPU 수행 관련 하드웨어 값
- Program Counter
- Registers
CPU에다 어떤 레지스터 값을 넣어서 실행하고 있었는지 등을 나타냅니다.
(3) 메모리 관련
code, data, stack이 메모리의 어디에 위치해있는지에 대한 정보를 나타냅니다.
(4) 파일 관련
해당 프로세스가 어떤 파일들을 사용하고 있는지에 대한 정보를 나타냅니다.
2. 문맥 교환 (Context Switch)
CPU를 한 프로세스에서 다른 프로세스로 넘겨주는 과정입니다.
CPU는 굉장히 빠른 자원입니다. 그래서 어떤 프로세스가 CPU를 계속해서 장악하는 것이 아니라 짧은 간격으로 CPU를 얻었다가 뺏기는 과정이 반복됩니다. 그래서 CPU를 뺏겼다가 나중에 다시 얻으면 처음부터 실행되는 것이 아니라 문맥을 기억해 두었다가 그 시점부터 실행을 해줄 수 있게 하는 것이 문맥 교환입니다.
CPU가 다른 프로세스에 넘어갈 때 운영체제는 다음을 수행합니다.
- CPU를 내어주는 프로세스의 상태를 그 프로세스의 PCB에 저장
- CPU를 새롭게 얻는 프로세스의 상태를 해당 PCB에서 읽어옴
사진을 보시면 어떤 프로세스 A가 CPU에서 실행중이라고 한다면, 프로그램 카운터(PC)가 어딘가를 가리키고 있고 레지스터에는 어떤 값을 넣어서 실행하고 있고, 메모리에는 정보가 있고 하는 식으로 실행이 되고 있었을 겁니다.
그런데 인터럽트가 들어왔다던지 하는 경우로 인해 이 프로세스가 CPU를 빼앗겨야된다면 위 정보들을 지우는 것이 아니라 다음 CPU를 얻었을 때 실행을 재개할 수 있게끔, 레지스터에 저장되어있던 값을 그 프로세스의 PCB에다가 저장을 해놓습니다.
여기서 헷갈리기 쉬운 개념이 한 가지가 있습니다. 바로 시스템 콜이나 하드웨어 인터럽트 발생 시 반드시 Context switch가 일어나는 것은 아니라는 것입니다.
위에서 말씀드렸다시피 Context switch는 사용자 프로세스 하나로부터 또 다른 사용자 프로세스로 CPU가 넘어가는 과정이라고 설명했습니다.
하지만 시스템 콜이나 하드웨어 인터럽트가 발생하면 CPU가 사용자 프로세스에서 운영 체제로 넘어갑니다. 이는 Context switch가 아닙니다. 위 같은 상황에서는 운영체제가 작업(인터럽트 서비스 루틴이나 시스템 콜이라면 관련 커널 함수를 실행)을 실행하고 함수가 끝난다면
CPU를 원래 커널로 넘어오기 전의 프로세스에 다시 넘겨주게 됩니다. (사진의 1과 같은 상황)
반면에, 타이머 인터럽트 같은 경우는 CPU를 다른 프로세스한테 넘기기 위한 의도를 가진 인터럽트입니다. 그래서 타이머 인터럽트가 들어오면 실행 중이던 사용자 프로세스에 할당된 CPU 시간이 끝나서 타이머 인터럽트가 발생한 것이기 때문에, 운영체제 커널은 CPU를 다른 사용자 프로세스에게 넘기게 되고 이것은 문맥 교환이 일어난 것입니다.
또 I/O 작업의 경우에는 오래 걸리는 일이기 때문에, I/O요청을 끝낸 후에 다시 프로세스에 CPU를 돌려주어도 당장 인스트럭션 실행이 불가능한 blocked가 되었기 때문에 다른 프로세스에 CPU를 넘겨주게 됩니다. (사진의 2와 같은 상황)
정리하자면 CPU 제어권이 다른 프로세스로 넘어가면 문맥교환이고, 다른 프로세스로 넘어가지 않았다면 문맥 교환이 아닙니다.
3. 프로세스를 스케줄링하기 위한 Queue
앞 포스팅에서 작업을 기다리기 위해 프로세스들이 queue에 줄 서있는 모습을 보여드렸습니다.
이러한 queue들은 다음으로 나뉘어서 설명드릴 수 있습니다.
1. Job queue
현재 시스템 내에 있는 모든 프로세스의 집합을 의미합니다.
2. Ready queue
현재 메모리 내에 있으면서 CPU를 기다리는 프로세스의 집합을 말합니다.
3. Device queue
I/O 디바이스의 처리를 기다리는 프로세스의 집합을 말합니다
사진은 각 디바이스마다 queue가 있는 것이고 queue의 헤더들이 PCB들을 줄줄이 연결한 것입니다. 위의 PCB 구조를 보시면 Pointer가 있는 것을 확인할 수 있는데, 그 포인터를 통해 연결이 되어있습니다.
프로세스 스케줄링 Queue의 모습
위 사진도 앞의 포스팅에서 보았던 것과 설명이 같습니다.
프로그램이 메모리에 올라오면 Ready queue에 등록되고, 자신의 차례가 오면 CPU를 얻어 실행합니다. I/O 요청이 들어오거나 할당 시간이 끝나면 다시 Ready queue에서 줄을 섭니다. 이후 CPU에서 본인의 역할이 끝나면 terminate 되어 빠져나가게 됩니다
4. 스케줄러(Scheduler)
1. 단기 스케줄러(Short-term scheduler or CPU scheduler)
매우 짧은 시간 단위로 스케줄이 이루어지며, 다음번에 어떤 프로세스에게 CPU를 줄지를 결정합니다.
2. 장기 스케줄러 (Long-term scheduler or Job scheduler)
메모리를 어떤 프로세스에게 줄 지를 결정합니다. 프로세스가 시작이 될 때 New 상태가 되는데, 이 프로세스가 CPU 제어권을 얻기 위해서는 Ready 상태에 있어야 합니다. 여기서 Job scheduler가 Ready 상태로 넘어오는 것을 admit 해주는 것입니다. 즉 Job scheduler는 New 상태의 프로세스 중에 어떤 것을 Ready Queue로 보낼지를 결정합니다.
또 Degree of multiprogramming을 제어합니다. Degree of multiprogramming란 메모리에 여러 프로그램이 동시에 올라가는 개념을 말합니다. 즉, 메모리에 올라가 있는 프로세스의 수를 제어하는 것입니다.
메모리에 너무 많은 프로그램이 동시에 올라가면 컴퓨터 전체의 성능이 안 좋아지고, 또 너무 적게 올라가도 성능이 좋지 않습니다. 만약, 너무 많은 프로그램이 CPU에 올라가게 되면 당장 필요한 부분도 메모리에 올라와있지 못해 실행할 수 없는 경우가 생기고, 또 반대로 너무 적게 올라가면 하나의 프로그램이 다른 작업을 하는 동안 넘겨 받을 CPU가 없는 문제가 생깁니다. 그래서 컴퓨터 시스템에서 Degree of multiprogramming을 제어하는 것은 중요하고 잡 스케줄러가 이것을 제어하는 스케줄러입니다.
현재 보통 저희가 사용하는 시스템에는 이런 장기 스케줄러가 없습니다.
3. 중기 스케줄러(Medium-term scheduler or Swapper)
저희가 사용하는 시스템에서는 이 Degree of multiprogramming을 중기 스케줄러를 이용해서 제어합니다. 장기 스케줄러는 프로그램이 새로 등록될 때 메모리를 줄지 말지 결정하는 역할을 수행한다고 언급했습니다. 하지만 지금의 시스템들은 무조건 메모리를 주게 되어있습니다. 그런데 이런 식으로 하다 보니 메모리에 너무 많은 프로그램이 동시에 올라가는 문제가 생깁니다. 이를 해결하기 위해 중기 스케줄러가 필요한데 다른 말로는 스와퍼라고도 합니다.
만약 메모리에 너무 많은 프로그램이 동시에 올라가 있으면 이 스와퍼가 일부 프로그램을 골라 메모리에서 통째로 쫓아냅니다. 이런 방식을 통해 메모리에 올라가 있는 프로세스의 수를 조절해 시스템의 성능을 좋아지게 합니다.
현대 운영체제에서는 장기 스케줄러 대신 중기 스케줄러가 들어가 있기 때문에 앞 포스팅에서 설명한 프로세스의 상태도 조금은 바뀌어있습니다.
5. 프로세스의 상태 (중기 스케줄러의 도입으로 변경된)
원래 프로세스의 상태가 Running, Ready, Blocked 세 가지였다면, Suspended(stopped)라는 상태가 추가되었습니다.
원래의 세 가지 상태로는 메모리를 통째로 빼앗긴 프로세스의 상태가 표현이 되질 않습니다. 메모리를 통째로 빼앗긴 프로세스는 CPU를 얻어도 아무 일을 하지 못하는데, 그런 상태는 Running도 Ready도 Blocked도 아니게 됩니다. Blocked는 CPU를 잡고 일을 하던 프로세스가 I/O 작업 같은 다른 곳의 오래 걸리는 작업을 위해 다른 곳에서 작업을 하는 것입니다.
이 Suspended라는 작업은 CPU뿐 아니라 외부에서도 이 프로세스를 강제로 정지시켜 놓은 상태입니다. 즉 메모리가 통째로 빼앗겨, 하던 일을 멈추고 정지가 된 것입니다.
즉 Blocked 와의 차이를 정리하자면 Blocked는 자신이 요청한 event가 만족되면 Ready 상태가 되는 것이고, Suspended는 외부에서 resume 해주어야 활성화되는 차이가 있습니다
6. 프로세스의 상태도 (중기 스케줄러의 도입으로 변경된)
Suspended는 Blocked 상태에서 Suspend가 되었는지, Ready 상태에서 Suspend가 된 건지에 따라 두 가지 상태로 표현이 되었습니다. 또 inactive라는 점선으로 구분된 것을 볼 수 있는데, 이는 외부에서 프로세스를 정지시켰다면 다시 외부에서 재개를 해주어야 위에 active로 올라가는 것을 나타낸 것입니다. Suspended Blocked에서는 I/O와 같은 오래 걸리는 작업이 실행이 되면 Suspended Ready로 바뀔 수는 있습니다. 하지만 CPU 관점에서는 아무 일도 할 수 없다는 것을 알아두어야 합니다.
참고자료
[KOCW 이화여대 반효경 교수님 - Process 1]
https://core.ewha.ac.kr/publicview/C0101020140318134023355997?vmode=f
[Operating System Concepts - Abraham Silberschatz]
https://www.yes24.com/Product/Goods/89496122