프로세스는 실행 중인 프로그램입니다
파일이 책장에 꽂힌 책이라면, 프로세스는 지금 펼쳐서 읽고 있는 책에 가깝습니다. 디스크에 설치된 프로그램은 아직 가만히 있는 파일입니다. 사용자가 명령을 실행하거나 서비스가 시작되면 그 프로그램은 메모리에 올라가고 CPU 시간을 나누어 쓰며 동작합니다. 이 실행 중인 단위를 프로세스라고 합니다.
시스템이 느려졌을 때 초보자는 보통 "Linux가 멈췄다"고 느낍니다. 하지만 실제로는 특정 프로세스 하나가 CPU를 많이 쓰거나, 메모리를 지나치게 차지하거나, 디스크 입출력을 기다리는 경우가 많습니다. 프로세스를 읽을 수 있으면 문제의 범위를 좁힐 수 있습니다.
먼저 안전한 확인 명령부터 실행해 보겠습니다. 현재 작업 위치는 중요하지 않지만, 습관을 위해 확인합니다.
pwd
whoami프로세스 확인 명령은 대부분 시스템 상태를 읽기만 합니다. 그래서 비교적 안전합니다. 다만 종료 명령인 kill, killall, pkill은 실행 중인 작업을 멈출 수 있으므로 뒤에서 확인 절차를 함께 익히겠습니다.
AI 생성 이미지
ps aux로 현재 실행 목록 읽기
ps는 process status의 줄임말로, 현재 실행 중인 프로세스 정보를 보여 줍니다. 가장 널리 쓰는 형태는 다음입니다.
ps aux출력이 길게 지나가면 다음처럼 less로 한 화면씩 볼 수 있습니다.
ps aux | less여기서 |는 앞 명령의 출력을 뒤 명령으로 넘기는 기호입니다. 파이프라인은 뒤 장에서 자세히 다루지만, 지금은 "긴 출력 결과를 천천히 읽기 위해 less에 넘긴다"고 이해하면 충분합니다. 종료는 q를 누릅니다.
ps aux의 주요 열은 다음처럼 읽습니다.
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.0 0.1 167000 12000 ? Ss 09:00 0:02 /sbin/init
user 2350 12.5 3.2 900000 260000 pts/0 Sl+ 10:10 0:15 python3 app.pyUSER: 프로세스를 실행한 사용자입니다.PID: 프로세스 ID입니다. 프로세스를 구분하는 번호이며 종료할 때 자주 사용합니다.%CPU: CPU 사용 비율입니다. 순간적인 값이라 계속 변할 수 있습니다.%MEM: 물리 메모리 사용 비율입니다.RSS: 실제 메모리에 올라와 있는 크기입니다. 메모리 문제를 볼 때%MEM과 함께 확인합니다.TTY: 연결된 터미널입니다.?는 특정 터미널에 직접 묶여 있지 않다는 뜻입니다.STAT: 프로세스 상태 코드입니다.COMMAND: 실행된 명령입니다.
전체 목록이 너무 많으면 특정 이름을 찾고 싶어집니다. 아직 텍스트 검색 도구를 깊게 배우기 전이라면 다음처럼 pgrep을 사용할 수 있습니다.
pgrep -a python-a는 PID뿐 아니라 실행 명령까지 보여 줍니다. 예를 들어 python이 들어간 프로세스를 찾을 때 유용합니다.
PID, PPID, 상태 코드를 해석하기
프로세스는 혼자 생겨나지 않습니다. 대부분 어떤 프로세스가 다른 프로세스를 실행합니다. 부모 프로세스의 ID를 PPID라고 합니다.
ps -efps -ef 출력에는 PID와 PPID가 함께 나옵니다.
UID PID PPID C STIME TTY TIME CMD
user 3001 2100 0 10:20 pts/0 00:00:00 bash
user 3050 3001 0 10:21 pts/0 00:00:00 sleep 300여기서는 sleep 300의 PID가 3050, PPID가 3001입니다. 즉 bash 셸이 sleep 명령을 실행한 것입니다. 어떤 프로그램이 왜 실행됐는지 추적할 때 PPID가 단서가 됩니다.
상태 코드도 중요합니다. ps aux의 STAT 열에는 한 글자 또는 여러 글자가 나옵니다.
R: 실행 중이거나 실행 대기 중입니다.S: 잠자는 상태입니다. 입력, 시간, 네트워크 응답 등을 기다리는 정상 상태가 많습니다.D: 중단하기 어려운 대기 상태입니다. 주로 디스크나 네트워크 파일 시스템 입출력을 기다릴 때 보입니다.T: 정지된 상태입니다.Ctrl+Z나 디버거 때문에 멈췄을 수 있습니다.Z: 좀비 프로세스입니다. 실행은 끝났지만 부모 프로세스가 종료 결과를 아직 회수하지 않은 상태입니다.
Z가 하나 보인다고 바로 시스템이 망가진 것은 아닙니다. 하지만 같은 좀비 프로세스가 계속 늘어난다면 부모 프로세스나 서비스에 문제가 있을 수 있습니다. D 상태는 kill -9로도 즉시 사라지지 않을 수 있습니다. 이때는 프로세스가 기다리는 디스크, 네트워크, 장치 문제까지 의심해야 합니다.
top과 htop으로 실시간 상태 보기
ps가 사진이라면 top은 실시간 감시 화면입니다.
top위쪽에는 시스템 전체 상태가 나오고, 아래에는 프로세스 목록이 계속 갱신됩니다. 종료하려면 q를 누릅니다.
처음 볼 때는 위쪽의 세 가지를 먼저 확인합니다.
top - 10:30:01 up 2:15, 1 user, load average: 0.42, 0.35, 0.30
%Cpu(s): 5.0 us, 2.0 sy, 0.0 ni, 92.0 id, 1.0 wa
MiB Mem : 7800 total, 1200 free, 3000 used, 3600 buff/cacheload average는 1분, 5분, 15분 동안의 평균 작업 대기 정도를 보여 줍니다. CPU 코어가 1개인 시스템에서 로드 평균이 1이면 거의 꽉 찬 상태에 가깝습니다. CPU 코어가 4개라면 로드 평균 4 정도가 비슷한 의미입니다. 정확한 코어 수는 다음으로 확인할 수 있습니다.
nprocCPU 항목에서 id는 idle, 즉 놀고 있는 비율입니다. wa는 I/O wait로, CPU가 계산할 일은 있지만 디스크나 입출력을 기다리는 비율입니다. CPU 사용률은 낮은데 시스템이 느리고 wa가 높다면 CPU보다 디스크나 저장 장치 쪽을 의심합니다.
top 안에서는 다음 키가 유용합니다.
P: CPU 사용률 기준 정렬M: 메모리 사용률 기준 정렬k: 프로세스 종료 신호 보내기q: 종료
초보자에게는 htop이 더 보기 쉽습니다. 색상과 막대 그래프로 CPU, 메모리, 프로세스를 보여 주고 키 안내도 화면 아래에 표시됩니다. 설치되어 있지 않다면 배포판에 맞게 설치합니다.
Ubuntu/Debian 계열:
sudo apt update
sudo apt install htopFedora/RHEL 계열:
sudo dnf install htopArch 계열:
sudo pacman -S htop실행은 간단합니다.
htophtop에서도 종료는 F10 또는 q입니다. 프로세스를 선택하고 F9를 누르면 종료 신호를 보낼 수 있지만, 초보자는 먼저 PID와 명령 이름을 확인한 뒤 터미널에서 명시적으로 kill을 실행하는 편이 실수를 줄입니다.
nice와 renice로 우선순위 조정하기
Linux는 여러 프로세스가 CPU를 나누어 쓰도록 스케줄링합니다. 이때 프로세스의 CPU 우선순위에 영향을 주는 값이 nice 값입니다. 이름 그대로 "다른 프로세스에게 얼마나 친절하게 양보할 것인가"에 가깝습니다.
nice 값은 보통 -20부터 19까지입니다.
값이 낮을수록 우선순위가 높습니다.
값이 높을수록 우선순위가 낮습니다.
일반 사용자는 보통 자기 프로세스의 nice 값을 높여서 우선순위를 낮출 수 있습니다.
우선순위를 높이려면 관리자 권한이 필요합니다.
처음부터 낮은 우선순위로 명령을 실행하려면 nice를 사용합니다.
nice -n 10 tar -czf archive.tar.gz ~/linux-practice이 명령은 압축 작업을 일반 작업보다 조금 양보하게 만듭니다. 큰 파일 압축이나 백업처럼 오래 걸리지만 급하지 않은 작업에 적합합니다.
이미 실행 중인 프로세스의 nice 값을 바꾸려면 renice를 사용합니다.
renice -n 10 -p 3050PID 3050 프로세스의 우선순위를 낮춥니다. 반대로 값을 낮춰 우선순위를 높이려면 보통 sudo가 필요합니다.
sudo renice -n -5 -p 3050우선순위를 높이는 것은 신중해야 합니다. 중요한 시스템 서비스보다 내 작업을 앞세우면 전체 반응성이 나빠질 수 있습니다. 초보자는 "느린 작업을 조금 양보시키는 용도"로 먼저 익히는 것이 안전합니다.
kill, killall, pkill의 차이
프로세스를 종료할 때 가장 기본이 되는 명령은 kill입니다. 이름은 강해 보이지만, 실제로는 프로세스에 신호(signal)를 보내는 명령입니다.
가장 안전한 기본 흐름은 다음입니다.
pgrep -a sleep
kill 3050kill 3050은 기본적으로 SIGTERM 신호를 보냅니다. SIGTERM은 "정리하고 종료해 달라"는 요청입니다. 프로그램이 이 신호를 받으면 파일 저장, 임시 파일 삭제, 연결 종료 같은 마무리 작업을 할 수 있습니다.
그래도 종료되지 않을 때 마지막 수단으로 SIGKILL을 사용합니다.
kill -9 3050또는 이름으로 씁니다.
kill -KILL 3050SIGKILL은 프로세스가 거부할 수 없습니다. 대신 프로그램이 정리할 시간을 갖지 못합니다. 작성 중인 파일이 깨지거나 임시 상태가 남을 수 있습니다. 따라서 순서는 항상 다음처럼 생각합니다.
프로세스 이름과 PID를 확인합니다.
먼저
kill PID로SIGTERM을 보냅니다.몇 초 기다린 뒤
ps나pgrep으로 남아 있는지 확인합니다.정말 멈추지 않을 때만
kill -9 PID를 사용합니다.
비슷한 명령으로 killall과 pkill이 있습니다.
killall firefox
pkill -f "python3 app.py"killall은 지정한 이름의 프로세스를 종료합니다. 이름이 같은 프로세스가 여러 개면 함께 영향을 받을 수 있습니다. pkill은 패턴으로 프로세스를 찾아 신호를 보냅니다. -f를 붙이면 명령 전체 줄에서 찾기 때문에 강력하지만 위험도도 커집니다.
초보자에게 권하는 순서는 이렇습니다.
PID를 정확히 알면
kill PID를 사용합니다.같은 이름의 프로세스를 모두 종료해도 되는 상황에서만
killall 이름을 사용합니다.검색 패턴을 충분히 확인한 뒤에만
pkill을 사용합니다.
pkill을 실행하기 전에는 같은 조건으로 pgrep을 먼저 실행합니다.
pgrep -a -f "python3 app.py"
pkill -f "python3 app.py"이렇게 하면 어떤 프로세스가 종료 대상인지 눈으로 확인할 수 있습니다.
터미널 작업을 백그라운드로 보내기
터미널에서 명령을 실행하면 보통 그 명령이 끝날 때까지 프롬프트가 돌아오지 않습니다. 짧은 명령은 괜찮지만, 오래 걸리는 작업은 터미널 하나를 계속 붙잡습니다. 이때 작업 제어(job control)를 사용합니다.
간단한 실습을 해 보겠습니다.
sleep 300이 명령은 300초 동안 기다립니다. 프롬프트가 돌아오지 않습니다. 여기서 Ctrl+Z를 누르면 작업이 정지됩니다.
[1]+ Stopped sleep 300정지된 작업 목록은 jobs로 봅니다.
jobs출력 예시는 다음과 같습니다.
[1]+ Stopped sleep 300이 작업을 백그라운드에서 계속 실행하려면 bg를 사용합니다.
bg %1%1은 jobs 목록의 1번 작업을 뜻합니다. 다시 앞쪽으로 가져오려면 fg를 사용합니다.
fg %1처음부터 백그라운드로 실행하려면 명령 끝에 &를 붙입니다.
sleep 300 &
jobs백그라운드 작업도 현재 터미널과 연결되어 있습니다. 터미널을 닫으면 함께 종료될 수 있습니다. 터미널을 닫아도 계속 실행하고 싶다면 nohup을 사용합니다.
nohup sleep 300 &nohup은 터미널 연결이 끊겨도 명령이 끊기지 않도록 실행합니다. 출력은 기본적으로 nohup.out 파일에 저장될 수 있습니다. 실제 백업이나 장시간 작업에서는 출력 파일을 명시하는 편이 좋습니다.
nohup long-running-command > work.log 2>&1 &여기서 > work.log 2>&1은 표준 출력과 오류 출력을 파일로 모으는 표현입니다. 자세한 리다이렉션 문법은 뒤에서 다루지만, 지금은 "터미널에 찍힐 내용을 로그 파일에 저장한다"고 이해하면 됩니다.
실습 과제: 느린 작업 찾아보기
다음 실습은 안전한 명령만 사용합니다.
백그라운드 작업을 하나 만듭니다.
sleep 600 &작업 목록을 확인합니다.
jobsPID를 찾습니다.
pgrep -a sleepps로 상태를 확인합니다.
ps -o pid,ppid,stat,ni,cmd -p PID위 명령에서 PID는 실제 숫자로 바꿉니다. ni는 nice 값을 뜻합니다.
우선순위를 낮춥니다.
renice -n 10 -p PID정상 종료 신호를 보냅니다.
kill PID남아 있는지 확인합니다.
pgrep -a sleep아무것도 출력되지 않으면 종료된 것입니다.
문제 해결 시나리오: 시스템이 갑자기 느려졌을 때
터미널 반응이 느려지고 팬 소리가 커졌다고 가정하겠습니다. 바로 재부팅하기 전에 다음 순서로 확인합니다.
top먼저 CPU 사용률이 높은 프로세스를 봅니다. P를 눌러 CPU 기준으로 정렬합니다. 특정 프로세스 하나가 계속 높은 CPU를 사용한다면 PID와 COMMAND를 기록합니다.
메모리가 부족해 보이면 M을 눌러 메모리 기준으로 정렬합니다. 브라우저, 개발 서버, 데이터 처리 프로그램처럼 메모리를 많이 쓰는 작업이 있는지 확인합니다.
로드 평균은 높은데 CPU가 많이 바쁘지 않고 wa가 높다면 디스크 대기 문제일 수 있습니다. 이때 무작정 kill -9를 쓰기보다, 파일 복사, 압축, 백업, 업데이트 작업이 진행 중인지 먼저 확인합니다.
종료가 필요하다고 판단하면 다음 순서를 지킵니다.
pgrep -a -f "문제가_되는_명령_일부"
kill PID
pgrep -a -f "문제가_되는_명령_일부"정상 종료가 되지 않고, 해당 프로세스가 사용자 작업이며 종료해도 되는 것이 확실할 때만 마지막으로 실행합니다.
kill -9 PID프로세스 관리는 "빨리 죽이는 기술"이 아닙니다. 현재 무엇이 실행 중인지 읽고, 어떤 자원을 쓰는지 판단하고, 가능한 한 정상 종료를 요청하는 절차입니다. 이 습관이 있으면 시스템이 느려졌을 때도 당황하지 않고 원인을 좁혀 갈 수 있습니다.
이 노트는 보도·비평·교육·연구 목적으로 작성되었습니다. 저작권 문의가 있으시면 에서 알려주세요.