프로세스(process) : 실행 중인 프로그램
프로그램 : 디스크 상에 존재하며 실행을 위한 명령어와 정적 데이터의 묶음
운영체제 : 이 명령어와 데이터 묶을을 읽고 실행하여 프로그램에 생명을 불어넣는 것
운영체제는 CPU를 가상화하여 이러한 환상을 만들어 낸다.
시분할(time sharing)
공간 분할(space sharing)
운영체제에서 CPU 가상화를 잘 구현하기 위해 다음이 필요
메커니즘 : 필요한 기능을 구현하는 방법이나 규칙
지능 : 정책(policy)의 형태로 표현
정책 : 운영체제 내에서 어떤 결정을 내리기 위한 알고리즘
프로세스의 구성 요소를 이해하기 위해서 하드웨어 상태(machine state)를 이해해야 한다.
프로그램이 실행되는 동안 하드웨어 상태를 읽거나 갱신할 수 있다.
하드웨어 상태 중 가장 중요한 요소는 메모리
명령어는 메모리에 저장
프로그램이 읽고 쓰는 데이터 역시 메모리에 저장
프로세스가 접근할 수 있는 메모리(주소 공간(address space))는 프로세스를 구성하는 요소
레지스터도 하드웨어 상태를 구성하는 요소 중 하나
많은 명령어들이 레지스터를 직접 읽거나 갱신
특별한 레지스터
- 프로그램 카운터(program counter, PC) : 프로그램의 어느 명령어가 실행 중인지를 알려준다.
- PC는 명령어 포인터(instruction pointer, IP)라고도 불린다.
- 스택 포인터(stack pointer)와 프레임 포인터(frame pointer)는 함수의 변수와 리턴 주소를 저장하는 스택을 관리할 때 사용하는 레지스터
운영체제는 새로운 프로세스를 생성할 수 있는 방법을 제공해야 한다. 쉘에 명령어를 입력하거나, 응용 프로그램의 아이콘을 더블-클릭하여 프로그램을 실행시키면, 운영체제는 새로운 프로세스를 생성한다.
운영체제는 프로세스를 강제로 제거할 수 있는 인터페이스를 제공해야 한다. 프로세스가 스스로 종료하지 않으면 필요없는 프로세스를 중단시키는 API는 매우 유용할 것이다.
어떤 프로세스의 실행 중지를 기다릴 필요가 있기 때문에 여러 종류의 대기 인터페이스가 제공된다.
여러 가지 제어 기능들이 제공된다. 예를 들어, 대부분의 운영체제는 프로세스를 일시정지하거나 재개(일시정지되었던 프로세스의 실행을 다시 시작)하는 기능을 제공한다.
프로세스 상태 정보를 얻어내는 인터페이스도 제동된다. 상태 정보에는 얼마 동안 실행되었는지 또는 프로세스가 어떤 상태에 있는지 등이 포함된다.
프로그램 코드와 정적 데이터(static data)를 메모리, 프로세스의 주소 공간에 탑재(load)
프로그램은 디스크에 특정 실행 파일 형식으로 존재
코드와 정적 데이터를 메모리에 탑재하기 위해서는 운영체제는 디스크의 해당 바이트를 읽어서 메모리의 어딘가에 저장해야 한다.
프로그램을 실행하면서 코드나 데이터가 필요할 때 필요한 부분만 메모리에 탑재
코드와 정적 데이터가 메모리로 탑재된 후, 프로세스를 실행시키기 전에 운영체제가 해야 할 일이 몇 가지 있다.
운영체제도 일종의 프로그램이다. 다른 프로그램들과 같이 다양한 정보를 유지하기 위한 자료 구조를 가지고 있다.
예를 들어, 프로세스 상태를 파악하기 위해 준비 상태의 프로세스들을 위한 프로세스 리스트(process list)와 같은 자료 구조를 유지한다.
프로세스의 관리를 위한 정보를 저장하는 자료구조를 프로세스 제어 블록(Process Control Block, PCB)라고 부른다.
//프로세스를 중당하고 이후에 재개하기 위해
// xv6가 저장하고 복원하는 레지스터
struct context {
int eip;
int esp;
int ebx;
int ecx;
int edx;
int esi;
int edi;
int ebp;
};
//가능한 프로세스 상태
enum proc_state { UNUSED, EMBRYO, SLEEPING, RUNNABLE, RUNNING, ZOMBIE };
//레지스터 문맥과 상태를 포함하여
//각 프로세스에 대하여 xv6가 추적하는 정보
struct proc {
char *mem; // 프로세스 메모리 시작 주소
uint sz; // 프로세스 메모리의 크기
char *kstack; // 이 프로세스의 커널 스택의 바닥 주소
enum proc_state state; // 프로세스 상태
int pid; // 프로세스 ID
struct proc *parent; // 부모 프로세스
void *chan; // 0이 아니면 chan에서 수면
int killed; // 0이 아니면 종료됨
struct file *ofile[NOFILE]; // 열린파일
struct inode *cwd; // 현재 디렉터리
struct context context; // 프로세스를 실행시키려면 여기로 교환
struct trapframe *tf; // 현재 인터럽트에 해당하는 트랩 프레임
};
참고자료
OSTEP
운영체제: 아주 쉬운 세 가지 이야기