프로세스란
프로세스 vs 프로그램
- 프로그램: 디스크에 저장되어 있는 실행 가능한 파일. 메모리에 올라가 있지 않지만 실행시키면 메모리로 로드되어 실행할 수 있다. 실행시키면 디스크에 저장된 실행 파일이 버스를 타고 메모리 구조에 맞게 메모리에 올라간다(로드된다). 코드 세그먼트의 시작을 프로그램 카운터가 가리키게 되고 실행 중인 프로그램이 되는데, 이것을 프로세스라고 한다.
- 프로세스: 실행된 프로그램을 말하며, 프로그램을 실행하면 로더가 프로그램의 복사판을 만들어서 메모리에 올린다. 바이너리 코드, 즉 CPU 연산들의 집합으로 이루어져 있고 그게 코드 세그먼트로 복사된다. 프로그램이 실행되어 생성된 하나의 인스턴스라고 할 수 있다. 프로세스는 고유한 PID를 가지고 커널에 의해 관리된다. 커널은 PID 테이블을 가지고 스케줄링을 진행한다. 프로세스는 실행과 스케줄링의 기초 단위이다.
Process Address Space
- Virtual Memory 덕분에 모든 프로세스는 0x00000000부터 0xffffffff까지의 공간이 있다고 가정하고 사용할 수 있다. 하드웨어 메모리 주소를 기억하고 관리하기 어렵기 때문에 abstraction을 제공하는 것이다. MMU가 컨버팅을 담당한다.
- 주소 공간 구성: 프로세스의 주소 공간은 코드(텍스트) 세그먼트, static(데이터) 세그먼트, 힙, 스택으로 이루어져 있다. 프로그램 카운터가 코드 세그먼트에서 가리키는 부분을 Instruction Register에 복사하고, 명령을 실행하는 데 필요한 지역변수나 전역변수가 스택, 데이터 세그먼트, 힙에서 가져와서 General Purpose Register에 저장하고 메모리 공간에 계산한 값을 덮어쓰고 프로그램 카운터를 1 증가시키는 방식으로 프로그램이 실행된다.
- 코드 세그먼트: Address Space의 맨 아래에 코드 세그먼트가 적재되고 아래에서부터 프로그램 카운터가 한 칸씩 이동하면서 실행한다.
cout
과 같은 표준 라이브러리 함수를 사용하면 cout
코드가 존재하는 바이너리 파일의 주소로 점프했다가 돌아온다. 코드 세그먼트 영역은 readonly이다.
- 스택: 함수 수행에 필요한 메모리를 스택에 위에서부터 쌓는다. 쌓이는 단위를 스택 프레임이라고 하고, 각 함수에서 사용하는 지역변수, 매개변수가 스택 프레임 내에 저장된다.
- 힙: 동적으로 할당한 메모리가 위쪽으로 쌓인다. 런타임에 크기가 결정된다. 사용자가 동적으로 할당 및 해제한다.
- 데이터(Static) 세그먼트: 전역변수, static 변수 등을 저장하는 공간이다.
프로세스 상태값

- new: 프로세스 초기화 작업을 진행한다. PCB(프로세스 컨트롤 블록)을 생성하고 PID를 부여하며, 메모리 상에 프로세스 주소 공간을 만드는 등의 작업을 하고 완료되면 ready 큐에 들어간다.
- ready: 수행되기를 기다리는 프로세스이다. 지금 당장 CPU에 올라가서 수행해도 문제없는 프로세스들이 ready 큐에 들어가 있고, 현재 CPU에서 동작 중인 프로세스가 타이머 인터럽트나 I/O 요청으로 인한 시스템 콜 등에 의해 커널이 수행되면 현재 진행 중인 프로세스는 내려오고 인터럽트 핸들링을 한 다음 스케줄링을 통해서 다음 실행될 프로세스를 ready 큐에서 고른다.
- running: 스케줄러에 선정된 프로세스가 CPU에 의해 실행되는 상태. 타이머 인터럽트가 걸리거나 트랩을 걸었을 때, 혹은 waiting 프로세스가 하드웨어 인터럽트를 걸었을 때 내려와서 waiting으로 빠진다. 트랩이 걸렸을 때 처리가 끝나면 데이터를 waiting인 프로세스에 전달하면 그 프로세스는 ready 상태가 된다. 결과를 받아와야 다음 명령을 수행 가능한 ready 상태가 될 수 있기 때문이다.
- waiting: I/O 이벤트를 기다리는 등의 상황으로 인해 당장 수행될 수 없는 프로세스. 커널로부터 결과를 받아서 다음 명령을 수행할 수 있는 상태가 되면 ready가 된다.
- terminated: 프로세스가 종료되고 메모리에서 내려간다.
PCB
- PCB: 프로세스 컨트롤 블록. 프로세스가 어디까지 동작했고 파일이 어떻게 연결되어 있는지 등 프로세스가 CPU에서 내려갔다가 다시 올라갈 때 필요한 모든 정보를 갖고 있는 구조체. 커널에서 관리되고 있다. 리눅스 2.4 기준으로도 1456바이트로 크기가 상당히 크다. 모든 프로세스는 PCB를 기반으로 관리되며, 리눅스에서 PCB는 연결 리스트로 관리된다.
- PCB가 포함하는 정보: process state, program counter, register, 오픈된 파일 리스트, 스케줄링 정보, 메모리 정보, 부모, 자식 프로세스 등.
- PCB는 ready 상태일 때는 ready 큐에 존재하고, I/O 요청을 기다릴 때는 I/O Device 큐에 연결리스트로 존재한다.
Context Switching (CPU switching)
- 정의: 컨텍스트란 명령어들이 어디까지 수행되었는지에 대한 정보 및 명령을 수행할 때 필요한 기타 정보들을 합친 것이다. 하나의 프로세스가 수행되던 컨텍스트가 PCB에 저장되고 다른 프로세스로 스위칭되어 CPU에서 내려온다. 다시 CPU 사용 권한을 받으면 PCB에서 컨텍스트를 받아와서 다시 수행한다. 컨텍스트 스위칭은 일반적으로 1초에 100~1000번 정도 일어난다.