Process
프로세스
각 프로세스는 자신만의 메모리 공간을 갖고, OS 스케줄러가 CPU 시간을 나눠준다.
프로세스(Process)는 실행 중인 프로그램의 인스턴스로, 디스크에 있는 수동적 파일(program)과 달리 프로그램 카운터·레지스터·스택 같은 실행 상태를 가진 능동적 실체다. 커널은 각 프로세스를 프로세스 제어 블록(PCB, Process Control Block; Linux에서는 task_struct)이라는 자료구조로 표현하며, 여기에 프로세스 상태·PID·CPU 레지스터·스케줄링 정보·메모리 관리 정보·입출력 상태·계정 정보가 저장된다. 각 프로세스는 독립된 가상 주소 공간(address space)을 가지며 이는 text(컴파일된 코드), data(전역·정적 변수), heap(malloc/free로 동적 할당), stack(지역 변수·함수 프레임)의 네 영역으로 구성되고, heap과 stack은 자유 공간의 양 끝에서 서로를 향해 자란다. 프로세스는 new→ready→running→waiting→terminated의 다섯 상태를 오가며, ready에서 running으로는 스케줄러의 dispatch로, running에서 waiting으로는 I/O 요청 등으로, running에서 ready로는 타임 슬라이스 만료(preemption)로 전이한다. Unix에서 새 프로세스는 fork() 시스템 콜로 부모(parent)를 복제해 자식(child)을 만드는데, fork는 자식에게 0을, 부모에게 자식의 PID를 반환하며 현대 커널은 성능을 위해 Copy-on-Write(COW)로 주소 공간 복사를 지연시킨다. 프로세스들은 서로 격리되어 있으므로 협력하려면 파이프·공유 메모리·메시지 큐·소켓·시그널 같은 IPC 메커니즘이 필요하다.
내부 구성
핵심 포인트
- 프로세스 = 실행 중인 프로그램 인스턴스(능동적), 프로그램 = 디스크의 수동적 파일
- 커널은 각 프로세스를 PCB(task_struct)로 관리하며 상태·PID·레지스터·메모리·I/O 정보를 담는다
- 주소 공간은 text/data/heap/stack 4영역이며 heap과 stack이 서로를 향해 자란다
- 5가지 상태: new → ready → running → waiting → terminated (dispatch, preemption, I/O로 전이)
- fork()는 부모를 복제해 자식 생성, 자식엔 0·부모엔 자식 PID 반환, COW로 복사 지연
- 프로세스는 서로 격리되어 있어 협력하려면 IPC가 필수다
- 컨텍스트 스위칭 시 PCB에 현재 상태를 저장하고 다음 프로세스 상태를 복원한다
심화
면접 단골 질문은 'fork() 직후 부모와 자식이 공유하는 것과 복제되는 것'이다. Copy-on-Write 덕분에 fork 직후 부모와 자식은 물리 페이지를 공유하지만, 어느 한쪽이 쓰기를 시도하는 순간 해당 페이지만 복제된다. 또 fork() 후 exec()를 호출하면 자식의 주소 공간이 새 프로그램으로 완전히 교체되므로, 사실 fork로 복사한 페이지 대부분이 버려진다는 점(그래서 vfork·posix_spawn이 존재)까지 알면 좋다. 파일 디스크립터는 fork 시 복제되어 부모와 자식이 같은 파일 오프셋을 공유하는데, 이것이 쉘 파이프라인 구현의 핵심이다. 또 하나 자주 나오는 개념이 '좀비(zombie)'와 '고아(orphan)' 프로세스다. 자식이 종료되었지만 부모가 wait()로 종료 상태를 회수하지 않으면 PCB가 남아 좀비가 되고, 반대로 부모가 먼저 죽으면 자식은 고아가 되어 init(PID 1)이 입양해 정리한다. IPC 선택 기준도 중요한데, 공유 메모리는 가장 빠르지만 동기화(세마포어 등)를 직접 해야 하고, 메시지 큐·파이프는 커널이 동기화를 대신 해주지만 복사 비용이 있으며, 소켓만이 네트워크 경계를 넘을 수 있다는 트레이드오프를 설명할 수 있어야 한다.
쉽게 말하면 아파트의 각 세대(프로세스)는 독립된 공간을 갖고, 문을 통해서만(IPC) 소통.