들어가기
프로세스 관리는 리눅스를 다룰 때 가장 자주 마주치는 영역 중 하나입니다.
명령어를 실행하고, 멈추고, 백그라운드로 보내는 모든 동작은 결국 프로세스 관리로 귀결됩니다.
이 글에서는 프로세스의 정의를 나열하는 데서 그치지 않고,
운영 중 실제로 언제 어떤 판단을 해야 하는지를 기준으로 정리합니다.
프로세스란 무엇인가요?
프로세스는 메모리에 적재되어 실행 중인 프로그램을 의미합니다.
디스크에 존재하는 실행 파일은 아직 프로세스가 아니며,
실행되는 순간 운영체제로부터 PID를 부여받고 프로세스로 관리됩니다.
리눅스 시스템은 하나의 CPU 위에서 여러 프로세스를 처리합니다.
이를 위해 시분할(Time Sharing) 방식을 사용하며,
짧은 시간 단위로 CPU를 나누어 사용하기 때문에 동시에 실행되는 것처럼 보이게 됩니다.
프로세스는 어떤 정보로 관리될까요?
리눅스는 각 프로세스를 단순한 실행 단위가 아닌,
여러 속성을 가진 객체처럼 관리합니다.
- PID (Process ID) : 프로세스를 구분하기 위한 고유 번호입니다.
- Priority : CPU 스케줄링 시 적용되는 우선순위입니다.
- Nice value : Priority에 영향을 주는 보정 값으로, 낮을수록 우선순위가 높습니다.
- Memory : 코드, 데이터, 힙, 스택 영역을 포함한 메모리 사용 정보입니다.
- Security context : SELinux에서 사용하는 보안 정책 정보입니다.
- Environment : 실행 시 전달된 환경 변수 집합입니다.
- File handles : 열려 있는 파일, 소켓, 파이프 디스크립터입니다.
- Exit status : 종료 시 부모 프로세스에게 전달되는 결과 코드입니다.
이 정보들은 단순 조회용이 아니라,
문제 상황에서 원인을 추적하는 단서로 사용됩니다.
PID 1은 왜 중요할까요? (init → systemd)
리눅스에서 PID 1은 시스템의 시작점입니다.
부팅이 완료되면 가장 먼저 실행되며,
다른 모든 프로세스의 조상이 됩니다.
초기 리눅스에서는 init이 이 역할을 담당했습니다.
SysV init 방식은 스크립트를 순차적으로 실행하는 구조였으며,
단순하지만 부팅 속도가 느리고 의존성 관리가 어렵다는 문제가 있었습니다.
이를 개선하기 위해 등장한 것이 systemd입니다.
systemd 역시 PID 1로 동작하지만,
unit 기반으로 서비스를 관리하고 병렬 실행을 지원합니다.
이로 인해 부팅 속도가 개선되었고,
서비스 상태 확인과 재시작, 로그 관리가 표준화되었습니다.
- init : 스크립트 기반, 순차 실행
- systemd : unit 기반, 병렬 실행
프로세스 상태는 언제 확인해야 할까요?
프로세스는 실행 중 상황에 따라 여러 상태를 오갑니다.
상태를 이해하면, 프로세스가 멈춘 이유를 추측할 수 있습니다.
- running : CPU를 할당받아 실행 중이거나 실행 가능한 상태입니다.
- sleeping : 이벤트나 자원을 기다리는 정상 대기 상태입니다.
- uninterruptible sleep : I/O 작업을 기다리며 시그널로도 깨어나지 않는 상태입니다.
- stopped : SIGSTOP, SIGTSTP 등에 의해 일시 정지된 상태입니다.
- zombie : 실행은 종료되었으나 종료 상태가 회수되지 않은 상태입니다.
특히 zombie 상태는 프로세스 자체보다
부모 프로세스의 처리 문제를 의심해야 하는 신호입니다.
프로세스를 어떻게 확인할까요?
ps : 현재 실행 중인 프로세스 확인
ps는 특정 시점의 프로세스 상태를 확인할 때 사용합니다.
로그인한 터미널에서 어떤 프로세스가 실행 중인지 확인할 때 유용합니다.
bashps
ps -f
ps --forest
PPID를 함께 확인하면,
해당 프로세스가 어떤 부모 프로세스에 의해 실행되었는지 파악할 수 있습니다.
top : 실시간 상태 확인
top은 시스템이 느려졌다고 느껴질 때 가장 먼저 실행하는 명령어입니다.
- Shift + P : CPU 사용량 기준 정렬
- Shift + M : 메모리 사용량 기준 정렬
특정 프로세스가 자원을 과도하게 사용하고 있는지
빠르게 파악할 수 있습니다.
시그널은 언제 사용해야 할까요?
시그널은 프로세스에게 동작을 요청하는 수단입니다.
운영체제 내부뿐 아니라, 사용자가 직접 전달할 수도 있습니다.
- 커널 → 프로세스
- 프로세스 → 프로세스
- 사용자 → 프로세스
kill 명령어의 기본 시그널은 SIGTERM(15) 입니다.
이는 강제 종료가 아니라 정상 종료를 요청하는 신호입니다.
bashkill PID
kill -19 PID
정상 종료가 되지 않을 경우에만
보다 강한 시그널을 고려하는 것이 일반적입니다.
포그라운드와 백그라운드 전환
명령어 뒤에 &를 붙이면 백그라운드에서 실행됩니다.
bashsleep 10000 &
실행 중인 작업은 jobs로 확인할 수 있으며,
필요에 따라 포그라운드와 백그라운드를 전환할 수 있습니다.
fg: 백그라운드 → 포그라운드bg: 정지 상태 → 백그라운드
우선순위는 언제 조정할까요?
모든 프로세스가 동일한 중요도를 가지지는 않습니다.
CPU 자원을 덜 사용하도록 조정해야 하는 경우가 있습니다.
이를 위해 nice, renice 명령어를 사용합니다.
- nice 값 범위 : -20 ~ 19
- 기본값 : 0
- 값이 낮을수록 우선순위가 높습니다.
bashnice -n 10 command
renice -10 PID
일반 사용자는 0~19 범위만 사용할 수 있으며,
root 사용자만 전체 범위를 조정할 수 있습니다.
시스템 자원 상태 확인
프로세스 상태는 CPU와 메모리 상태와 함께 확인해야 합니다.
CPU
/proc/cpuinfoiostat -cmpstat
메모리
freevmstat/proc/meminfo/proc/swaps
자원 사용량을 함께 확인해야
프로세스 문제를 정확히 판단할 수 있습니다.
프로세스 문제를 만났을 때의 기본 흐름
- 시스템이 느려졌다면
top으로 자원 사용 현황을 확인합니다. - 원인이 되는 프로세스를 찾으면
ps로 PID와 부모 프로세스를 확인합니다. - 정상 종료가 가능하다면 SIGTERM을 먼저 전달합니다.
- 반복 생성된다면 부모 프로세스나 서비스 관리 방식을 확인합니다.
프로세스 관리는 명령어를 외우는 영역이라기보다,
시스템의 상태를 읽고 판단하는 과정에 가깝습니다.