도입
초창기 컴퓨터는 일괄 처리(Batch Processing) 방식이었습니다.
프로그램이 디스크에서 데이터를 읽어오는(I/O) 작업을 할 때, CPU는 할 일이 없어 자원 비효율이 발생했습니다.
"여러 프로그램을 메모리에 동시에 올려두고, 프로그램 A가 I/O 작업을 하느라 멈추면 그동안 CPU가 프로그램 B를 실행하게 만들면 효율이 극대화되지 않을까?"
- 엔지니어 -가설을 바탕으로 다중 프로그래밍(Multiprogramming) 환경을 설계했지만 문제가 발생합니다.
- 단순히 여러 코드를 메모리에 올려놓기만 하니, 프로그램 A가 오류를 일으켜 프로그램 B의 메모리 영역을 덮어써버리는 일이 발생했습니다. 하나가 죽으면 시스템 전체가 다운되는 구조였죠.
- CPU가 프로그램 A를 실행하다가 B로 넘어가려면(Context Switching), A가 어디까지 실행되었고 CPU 레지스터 값은 무엇이었는지 기억해야 합니다. 하지만 단순히 정적인 '코드' 덩어리만으로는 이 동적인 상태 변화를 추적하고 관리할 수 없었습니다.
결국 디스크에 누워있는 정적인 코드(프로그램)를 메모리에 올려 실행시키는 것만으로는 부족하다는 결론을 내립니다.
프로그램이 실행되면서 시시각각 변하는 '동적인 상태(메모리, 변수, 레지스터, 실행 흐름 등)'를 안전하게 격리하고 추적할 수 있는 껍데기가 필요해진 것입니다.
운영체제는 각 실행 흐름을 독립된 박스에 가두고, 서로의 영역을 철저히 분리하여 관리하기 시작했는데 이 박스가 바로 '프로세스'입니다.
즉, 프로세스는 "운영체제가 자원을 할당하고 보호하는 최소한의 격리 단위"로서 시스템의 안정성을 확보하고 CPU의 효율을 높이기 위해 도입되었습니다.
정의
코드는 하드디스크나 SSD에 저장된 정적인 '프로그램'입니다.
프로그램은 디스크에 저장된 정적 파일이지만, 프로세스는 메모리에 적재되어 CPU 자원을 배정받아 실행되는 “인스턴스”입니다. 같은 프로그램을 두 번 실행하면 프로세스는 두 개가 됩니다.
운영체제는 프로세스 단위로 PID(식별자), 주소 공간(가상 메모리), 열린 파일/소켓(FD), 권한/환경 변수 등을 관리합니다. 그래서 백엔드 장애/성능 이슈도 결국 “프로세스가 어떤 자원을 얼마나 점유하고 있는가”로 귀결되는 경우가 많습니다.
“프로세스는 단지 ‘실행 중’이 아니라,
자원과 권한을 가진 운영 단위이며, 운영체제는 이 단위를 중심으로 시스템을 통제한다.”
메모리 구조
운영체제는 프로세스마다 독립된 주소 공간을 제공하고, 그 안에서 메모리 영역을 논리적으로 분리합니다.
백엔드 개발자는 이 구조를 이해해야 OOM, StackOverflow, 메모리 누수 같은 문제를 “원인 단위”로 추적할 수 있습니다.

유형
서버 개발에서는 특히 “백그라운드 프로세스(데몬/서비스)”가 핵심입니다. 배치, 로그 수집, 모니터링 에이전트, 메시지 컨슈머 같은 구성 요소들이 대표적이고, 중단 없이 운영되도록 설계하는 것이 중요합니다.
상태
백엔드 성능 이슈에서 가장 중요한 포인트는 Running 자체가 느린지보다, Ready/Blocked에서 대기가 누적되는지입니다. (예: 락 대기, DB I/O 대기, 커넥션 풀 대기, 외부 API 대기)

통제
프로세스 관리는 단순 이론이 아니라 운영과 직결됩니다. 예를 들어 트래픽이 몰릴 때 Ready 대기가 길어지면 지연이 증가하고, 외부 의존성이 느려지면 Blocked 대기가 길어져 전체 처리량이 무너집니다.
프로세스 스케줄링
프로세스 동기화
프로세스 간 통신 (IPC)
생성과 종료 (fork/exec/exit)