
CPU는 메모리와 다르게 영역을 작은 piece들로 쪼갤 수 없다. 따라서 많은 프로그램들이 CPU의 전체 영역을 공유하게 된다. 하지만 각 시점에 하나의 프로그램만 CPU를 이용할 수 있다.
한 프로그램만 CPU를 사용할 수 있기 때문에 OS는 많은 CPU가 존재하는 것 같은 illusion을 주어야 한다.
즉 여러 프로그램이 각각 자신의 CPU를 갖고 있는 것 같은 착각을 갖도록 한다.
여기에 필요한 것이 Time sharing이다.
time sharing은 CPU Virtualization의 key technique이다. 우리는 CPU의 physical area를 sharing할 수는 없지만 time을 sharing할 수는 있다.
긴 시간을 작은 조각으로 쪼개서 각 조각을 하나의 프로그램에게 준다. 그 시간의 조각 동안 한 프로그램을 실행시키고 그 시간이 끝나면 프로그램의 실행을 멈추고 다른 프로그램으로 switch한다. 그리고 그 프로그램의 시간을 다 소모하면 다음 프로그램으로 switch한다. 이를 반복하면 많은 프로그램들이 자신만의 CPU를 소유하고 있다고 생각하도록 만들 수 있다.
time sharing에 드는 potential cost는 performance이다. performance는 switch를 할 때에 드는 overhead의 영향을 받는다.
time sharing을 하기 위해서는 OS가 언제든 running program의 상태를 저장(혹은 캡쳐, resume)할 수 있어야 한다. 프로그램을 실행하고 멈추고를 자유자재로 할 수 있어야 하기 때문...
즉, 이는 OS가 프로그램의 execution을 통제할 수 있어야 함을 의미한다.
프로그램을 멈춰야 한다면 프로그램을 멈춰서 어딘가에(메모리) 저장하고 대기하고 있던 다른 프로그램을 실행시켜야 한다. 따라서 OS는 running program의 상태를 capture 할 수 있어야 한다.
A process is a running program
프로그램이 실행되면 CPU나 메모리의 상태를 바꾸고 때로는 storage(ex. disk)를 바꾸기도 한다.
이 scope를 CPU와 메모리에 한정시키면 프로세스의 상태는 CPU상태와 메모리로 이루어져 있다.
CPU state와 memory를 capture할 수 있다면 running program을 표현할 수 있다.
c = a + b;와 같이 high-level programming에서는 한 줄로 보이는 코드여도 내부적으로는 load, store등의 여러 instruction이 실행된다. 한 instruction을 실행하면 CPU의 state가 바뀌고(CPU state라는 것은 결국 multiple register이므로 register가 바뀌는 것이다) CPU에서 메모리로 어떤 value를 저장하면 메모리도 바뀐다.
따라서 OS가 CPU와 메모리를 capture할 수 있다면 프로세스를 표현할 수 있게 된다.
CPU가 single instruction을 실행한 직후에는 아무것도 바뀌지 않으므로 그 때 CPU의 state를 저장하면 프로세스를 capture할 수 있다. 나중에 suspend되었던 프로그램을 다시 실행하고 싶으면 메모리에 저장해둔 값을 restore해서 resume하면 된다.

OS는 multiple program이 single CPU에서 동작할 수 있도록 해줌. 각 프로그램이 자신의 own CPU에서 동작하고 있는 듯한 illusion을 주어야 함.
OS는 프로세스를 manage하기 위해서 key data structure를 가지고 있다.
key data structure은 다음으로 이루어져 있다:
PCB는 각 프로세스에 대한 정보를 갖고 있는 C-structure이다.
PCB에는 register variable이 저장되어 있다. CPU의 레지스터 value를 메모리의 PCB에 저장하고 이것이 running program을 stop하는 방법이다.
xv6의 proc이 PCB의 역할을 하고 Linux에서는 이를 task struct라고 한다. 각 OS마다 사용하는 이름은 달라도 같은 컨셉을 사용하고 있다.
struct proc {
char *mem; // Start of process memory
uint sz; // Size of process memory
char *kstack; // Bottom of kernel stack
// for this process
enum proc_state state; // Process state
int pid; // Process ID
struct proc *parent; // Parent process
void *chan; // If non-zero, sleeping on chan
int killed; // If non-zero, have been killed
struct file *ofile[NOFILE]; // Open files
struct inode *cwd; // Current directory
struct context context; // Switch here to run process
struct trapframe *tf; // Trap frame for the
// current interrupt
};
proc은 PCB이며 PCB는 key structure이다. 가장 먼저 initialize하고 조심히 manage해야 한다. running program을 manage하기 때문이다. 그리고 이것이 CPU virtualization의 key이다.
mem, sz, kstack은 memory state를 capture하는데에 사용된다.
context는 CPU state를 capture하는데에 사용된다.