LINUX

프로세스는 어떻게 실행되는가(1/3): 프로세스 생성 과정

최서은 2026. 4. 13. 20:01

 

 

우리가 터미널에서 프로그램을 실행하거나 버튼을 클릭해 애플리케이션을 실행할 때, 단순히 “프로그램이 켜졌다”라고 생각하기 쉽습니다.

하지만 그 이면에서는 운영체제가 프로그램을 메모리에 올리고, 실행 단위를 생성하며, CPU가 작업을 처리할 수 있도록 여러 과정을 거치게 됩니다.

 

이때 중요한 개념이 바로 프로세스입니다.

리눅스에서는 이 프로세스가 fork와 exec이라는 과정을 통해 생성되고 실행됩니다.

 

이번 글에서는 프로그램이 실행될 때 내부에서 어떤 일이 일어나는지 흐름 중심으로 살펴보겠습니다.

 

 

 

 

 

프로그램

프로그램은 프로세스를 실행하는 데 사용하는 설계도라고 생각하면 됩니다.

기본적으로 프로그래밍 언어로 작성된 명령어의 집합이며, 이 명령어는 CPU가 실행할 수 있도록 기계어로 변환됩니다.

 

하지만 프로그램이 있다고 바로 실행되는 것이 아닌, 프로그램은 디스크에 저장된 코드입니다.

프로그램은 메모리에 로드되어 순차적으로 실행되기를 기다리고 있는 것입니다.

 

프로그램이 메모리에 로드되어 실행된다면 프로세스가 됩니다.

  • 프로그램 : 디스크에 저장된 실행 파일
  • 프로세스 : 메모리에 올라와 실행 중인 상태

 

 

 

프로세스


프로세스는 프로그램의 실행 인스턴스입니다. 간단히 말해 시스템에서 현재 실행 중인 프로그램을 의미합니다.

단순히 프로그래밍 언어로 작성된 프로그램이 실행되면, 운영체제가 이를 메모리에 적재하고 실행 단위를 생성하는데, 이 상태가 바로 프로세스입니다.

 

 

  • 계층 구조: 리눅스의 모든 프로세스는 부모-자식 관계를 가집니다. 특정 프로세스가 다른 프로세스를 생성하며, 자식은 부모의 속성을 상속받습니다.
  • 컨텍스트 스위칭(Context Switching): 여러 프로세스가 CPU를 나눠 쓰기 위해, 운영체제는 프로세스의 현재 상태(레지스터, PC 등)를 저장하고 복원하는 과정을 반복합니다.
  • 프로세스 제어 블록(PCB): 운영체제가 프로세스를 관리하기 위해 만드는 '신분증'입니다. 상태, PID, 프로그램 카운터 등이 담겨 있습니다.

 

 

 

 

 

 

프로세스 생성

프로세스는 단순히 만들어지는 것이 아니라, 운영 체제가 여러 단계를 거쳐 초기화 합니다.

 

프로세스 ID (PID) 할당

 

리눅스의 모든 프로세스에는 프로세스 ID(PID)라고 하는 고유 번호가 할당됩니다.

프로세스는 두 가지 방식으로 실행될 수 있습니다.

 

방법 1) 포어그라운드 프로세스(Foreground Process)

모든 프로세스는 기본적으로 시작되면 포어그라운드에서 실행되며 키보드에서 입력을 받고 화면으로 출력을 보냅니다.

sleep 10

 

위 작업이 완료될 때까지 터미널을 차단합니다.

 

 

방법 2) 백그라운드 프로세스(Background Process)

터미널과 독립적으로 실행되므로 다른 작업을 동시에 수행할 수 있습니다.

sleep 60 &
output:
[1] 2456

 

  • 1 : 작업 번호
  • 2465 : 프로세스 ID(PID)

 

메모리 할당

 

메모리에 있는 프로세스는 각각 다른 목적을 가진 여러 개의 독립적인 영역으로 나뉩니다.

  • Stack : 함수의 매개변수, 반환 주소, 지역 변수와 같은 임시 데이터가 저장됩니다.
  • Heap : 프로세스 실행 중에 동적으로 할당되는 메모리 영역입니다.
  • Data : 전역 변수를 포함합니다.
  • Text : 실행 가능한 명령어를 포함합니다. (일반적으로 읽기 전용) 

 

PCB 생성 및 초기화

 

프로세스를 관리하기 위한 PCB가 생성됩니다.

프로세스 제어 블록(PCB)에는 프로세스 상태, 프로그램 카운터(실행 시작 위치), CPU 레지스터 초기값 등과 같은 주요 정보가 포함됩니다.

 

 

 

 

 

fork()의 동작 원리

많은 운영체제, 특히 유닉스 계열 시스템에서 프로세스 생성은 fork() 시스템 호출을 사용합니다.

 

새로운 프로그램을 실행할 때, 처음부터 메모리를 0에서부터 할당하고 환경을 초기화하는 방식은 매우 비효율적입니다.

따라서 유닉스 계열 시스템은 이미 안정적으로 돌아가고 있는 부모 프로세스를 그대로 복제(fork)하는 방법으로 프로세스를 생성합니다.

 

실행 중인 프로세스가 fork()를 호출하면 운영체제는 새 프로세스를 생성합니다.

원래 프로세스는 부모 프로세스가 되고, 새로 생성된 프로세스는 자식 프로세스가 됩니다.

 

생성된 자식 프로세스는 원래 부모 프로세스의 복사본이지만, 고유한 프로세스 ID를 갖습니다.

자식 프로세스를 생성한 후에는 부모 프로세스와 자식 프로세스 모두 정상적으로 실행됩니다.

 

fork() 시스템 호출은 메모리 사용을 최적화하기 위해 복사(copy-on-write) 방식을 사용합니다. 

이 방식은 자식 프로세스가 생성됐을 때 메모리를 바로 복사하지 않고 필요할 때만 복사하는 방식을 사용하여 불필요한 메모리 낭비를 방지합니다.

 

 

 

 

exec()의 역할

fork()를 통해 생성된 자식 프로세스는 부모 프로세스의 복사본이기 때문에, 아직 동일한 프로그램 상태를 유지하고 있습니다.
이 상태에서는 새로운 프로그램을 실행하는 것이 아니라 단순히 “복제된 프로세스”일 뿐입니다.

 

exe()는 현재 실행 중인 프로세스를 완전히 새로운 프로그램으로 교체하는 시스템 호출입니다.

프로세스 ID(PID)는 유지되지만, 메모리 공간(Stack, Heap, Data)은 새로운 프로그램으로 완전히 덮어씌워집니다.

 

실제 프로그램 실행은 위 두 단계를 통해 이루어집니다.

사용자 입력 → bash 실행 → fork() 호출 → 자식 프로세스 생성 → exec() 호출 → 새로운 프로그램 실행

 

 

 

 


 

이번 글에서 프로그램이 어떻게 프로세스로 탄생하는지 알아보았다면, 다음 글에서는 이 프로세스가 메모리 내부에서 구체적으로 어떤 구조로 존재하며, 그 안에서 실행 단위인 스레드가 어떻게 움직이는지를 다뤄보겠습니다.

 

 

 

 

 

 



 

 


학습용으로 작성한 포스팅이므로 오류가 있을 수 있습니다.

잘못된 내용이나 보완이 필요한 부분이 있다면 댓글로 알려주시면 감사하겠습니다.
궁금한 점도 편하게 남겨주세요.

 

 

 

출처

- Processes in Linux

https://www.geeksforgeeks.org/linux-unix/processes-in-linuxunix/

- Process Creation and Deletions in Operating Systems

https://www.geeksforgeeks.org/operating-systems/process-creation-and-deletions-in-operating-systems/

- Fork System Call in Operating System

https://www.geeksforgeeks.org/operating-systems/fork-system-call-in-operating-system/

- Process in Operating System

https://www.geeksforgeeks.org/operating-systems/process-in-operating-system/