자원은 1개. 하지만 cpu만 사용하는건 아니기 때문에 여러 프로그램이 나눠쓸 수 있다.
예를 들어 다음과 같이 cpu1개가 프로그램 하나를 실행하는 상태이다.
Multiple Process는 다음과 같이 실행되는 것처럼 보이지만, 사실 cpu 1개로 나눠쓰는 거다.
이렇게 cpu가 간섭하면서 프로그램을 여러개 돌아가면서 cpu를 사용할 수 있게 한다.
관리를 더 쉽게 하기 위해 OS가 cpu를 뺏어서 다시 프로세스에게 전달해주는 식으로 동작한다.
즉, CPU를 time sharing을 한다.
이렇게 OS가 있기 때문에 각각의 프로세스가 자신만의 cpu를 가진 것같은 환상을 만들어준다.
💡 A Process is a running program
프로세스는 실행중인 프로그램이다.
프로세스는 원래 disk에 있다가 memory에 적재한다.
프로그램 code를 메모리에서 Load한다. 프로세스의 주소 공간에다가.
프로그램의 run-time stack이 할당된다.
프로그램의 heap이 생성된다.
OS는 다른 초기화 업무를 수행한다.
프로그램은 main이라고 이름붙여진 entry point에서 실행이 시작된다.
이렇게 disk에 있는 값들을 읽어서 process의 메모리 공간에 Load한다.
프로세스는 세 가지 상태 중 하나가 될 수 있다.
→ 프로세스 리스트를 만들어서 여기서 준비중인 프로세스, block된 프로세스, 현재 실행중인 프로세스를 파악 가능. 그리고 레지스터 문맥 교환도 가능
// the registers xv6 will save and restore
// to stop and subsequently restart a process
struct context {
int eip; // Index pointer register
int esp; // Stack pointer register
int ebx; // Called the base register
int ecx; // Called the counter register
int edx; // Called the data register
int esi; // Source index register
int edi; // Destination index register
int ebp; // Stack base pointer register
};
// the different states a process can be in
enum proc_state { UNUSED, EMBRYO, SLEEPING,
RUNNABLE, RUNNING, ZOMBIE };
// the information xv6 tracks about each process
// including its register context and state
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
};
cpu가 다른 프로세스로 교환될 때 시스템은 다음과 같은 일을 한다.
Context switch time은 순수 오버헤드이다.
Context switch time은 하드웨어에 의존한다.