...
리눅스 프로세스 동작 원리
시스템이 구동 될 때, 커널은 /etc 에 위치한 init 이라는 스크립트를 실행함으로써 시스템 서비스들을 차례대로 시작시킨다.
이 서비스들은 데몬 프로그램(백그라운드)으로 구현되어 있기 때문에 로그인하지 않은 상태에서도 필요 작업들을 수행한다.
프로그램은 프로그램을 실행시킬 수 있는데, 이를 부모와 자식 프로세스라고 표현한다.
커널은 이러한 프로세스들을 구조화시킨 형태로 유지하기 위해서 PID 라는 프로세스 ID 정보를 가지고 있다.
예를들어, 위에서 말한 init은 항상 1번 PID 를 할당 받는다.
리눅스 프로세스 명령어
프로세스 정보 확인
프로세스 출력 (ps)
리눅스는 다중 사용자, 사용 작업 시스템이기 때문에 여러 개의 프로세스를 동시에 수행하기 때문에 항상 어떤 프로세스들이 실행되고 있는지 모니터링할 필요가 있다.
따라서 현재 시스템에서 실행 중인 프로세스에 관한 정보를 출력하여 사용자에게 정보를 제공하는 명령어가 필요한데 이때 사용하는 명령어가 ps이다.
윈도우에서 특정 프로세스가 실행 중인지 확인하거나 강제 종료하기 위해 작업 관리자를 사용하듯이,
리눅스에서는 ps 명령어가 자주 사용된다.
특히 GUI를 사용하지 않는 서버 환경에서는 대부분의 프로세스들이 백그라운드에서 동작하기 때문에 특정 프로세스가 동작 중인지 확인하기 위해서 많이 쓰인다.
bash 스크립트(script)를 통한 자동화에도 ps 명령어가 자주 사용되는데,
주로 특정 프로세스에 시그널(signal)을 보내야 할 때 PID(process id)를 식별하기 위해서 쓰이기도 하고, 프로세스가 중단되면 다시 실행시키기 위해 감시하는 목적으로 쓰이기도 한다.
$ ps [옵션] # /proc 디렉터리 이하에 프로세스와 연관된 가상 파일시스템의 내용을 토대로 프로세스 정보를 출력한다.
- 기본 프로세스 출력
- a : 터미널과 연관된 프로세스만 출력
- x : 터미널과 연관되지 않는 프로세스만 출력
- -A : 모든 프로세스 출력 (-e와 동일)
- -e : 모든 프로세스 출력
- -a : 세션 리더와 커미널과 연관되지 않은 프로세스를 제외하고 모든 프로세스를 출력
- 지정한 프로세스 출력
- p : 지정한 PID 목록의 정보만 출력
- -C : 지정한 프로세스의 실행 파일 이름의 정보만 출력
- -u : 특정 사용자의 프로세스 정보를 출력
- 프로세스 표시 형식
- u : 프로세스의 소유자 정보를 함께 출력
- l : BSD 형식의 긴 형식으로 출력
- e : 프로세스 정보와 함께 프로세스의 환경변수 정보도 출력
- -l : 긴 포맷으로 출력
- -o : 사용자 정의 형식 지정 가능
- 프로세스 장식
- f : 프로세스 계층을 텍스트 형식의 트리구조를 보여줌.
- -f : 전체 포맷으로 출력
옵션 | 의 미 |
a | 터미널과 연관된 프로세스 출력. 보통 x 옵션과 연계하여 모든 프로세스를 출력할때 사용 |
e | 프로세스에 관련된 환경 변수 정보 출력 |
f | 프로세스간 상속관계를 트리형식으로 출력 |
l | 프로세스의 정보를 길게 보여줌 |
u | 프로세스의 소유자를 기준으로 출력 |
x | 터미널에 종속되지 않는 프로세스 출력 |
p | 지정한 프로세스 출력 |
-a | 세션리더를 제외하고 터미널에 종속되지 않은 모든 프로세스 출력 |
-A | 모든 프로세스 출력 |
-C [process] | 뒤에 입력된 프로세스만 출력 |
-e | 모든 프로세스 출력 |
-f | 유닉스 스타일로 출력해줌 |
-o [value] | 출력 포맷을 지정함, 값에는 pid, tty, time 등을 지정한다. |
- BSD
- System V
ps 명령어는 다른 명령어들과의 차이라면 -(대쉬)가 안들어간 옵션이 있다는 것인데,
이는 전통유닉스(System V, BSD)에 따라 나뉜다.
System V 의 경우 -(대쉬)를 사용하고, BSD 같은 경우는 -(대쉬)가 없다.
물론 출력결과도 조금씩 다르다. 자신의 상황에 맞게 쓰면 된다.
ps 프로세스 도표 항목
프로세스 항목 | 의미 |
F | 프로세스 플래그 |
S | 프로세스 상태코드 |
UID | 프로세스 소유자이름 |
PID | 프로세스 고유식별자 |
PPID | 부모프로세스의 PID |
C | 프로세서 사용률 %로 표기 |
PRI | 프로세스의 우선순위. 높은값이 낮은 우선순위 |
NI | nice 값이며 19에서 -20값 |
SZ | 프로세스 이미지가 차지하는 물리적 페이지 크기 |
WCHAN | 대기중일때 커널 함수의 이름 |
STIME | 프로세스가 시작한 시간 |
TTY | 터미널의 종류 |
TIME | 총 CPU 사용시간 |
CMD | 프로세스의 실행 시 명령줄 |
ps -x 에서는 STAT 이라는 새로운 필드도 추가해서 보여주는데, 이는 프로세스의 현재 상태를 나타낸다.
프로세스 상태(STAT) | 의미 |
D | 인터럽트가 불가능한 대기상태로 일반적으로 입출력 시 의미 |
I | 커널 쓰레드가 유휴상태를 의미 |
R | 프로세스가 실행중이거나 실행 가능한 상태 의미 |
S | 인터럽트가 가능한 대기상태 |
T | 작업 제어신호에 의해 멈춤상태 |
t | 디버깅 중 디버거에 의해 멈춘상태 |
X | 프로세스 죽은 상태 |
Z | 좀비프로세스 |
< | 높은 우선순위 상태 |
N | 낮은 우선순위 상태 |
L | 페이지가 락된 메로리를 갖고있음 |
s | 세션 리더 |
| | 멀티 쓰레드 |
+ | 포어그라운드 프로세스 그룹 |
ps 옵션 조합 예제 (aux / -ef)
주로 쓰이는 인기 있는 옵션들에는 aux 나 -ef 등이 있다.
부모 프로세스와 자식 프로세스의 관계를 보려면 $ ps -ef 가
프로세스 상태를 보는 용도로는 $ ps aux 가 더 적당하다.
$ ps aux # 모든 터미널의 프로세스를 소유자 정보와 함께 프로세스 정보를 출력
$ ps aux | grep apache # 특정 프로세스(apache)만 출력
$ ps -ef # 현재 실행중인 모든 프로세스의 정보를 전체 포맷으로 출력
$ ps -ef | more # 모든 프로세스를 풀 포맷으로 보여준다, more명령어를 줘서 페이지단위로 출력
$ ps -ef | grep apache # 모든 프로세스의 출력값을 grep을 이용하여 apache가 포함된 라인들을 출력
# ...이외의 조합들
$ ps -p 1(프로세스 번호가 1인 프로세스 출력)
$ ps -u apache(계정이 apache인 프로세스들을 )
$ ps -fp [PID] # PID를 키워드로 프로세스 정보를 확인
$ ps -u root # 특정 사용자가 돌리는 프로세스의 정보를 알고 싶을 때
$ ps -p 1222 -o comm= # PID가 1222인 프로세스의 이름을 출력
$ ps -C httpd -o pid= # 이름이 httpd인 프로세스들의 pid를 출력
프로세스를 트리 형태로 출력 (pstree)
$ pstree [옵션]
옵션 | 의미 |
-a | 프로세스 명령줄 인자 출력 |
-h | 현재 프로세스와 부모 프로세스를 강조 표시 |
-n | 프로세스 이름 대신에 PID순으로 정렬 |
-p | PID와 함께 출력 |
-s | 특정 프로세스의 부모 프로세스를 출력 |
실시간 프로세스 출력 (top)
$ top [옵션] # 시스템에서 현재 실행중인 프로세스에 대한 정보를 실시간으로 제공.
옵션 | 의미 |
-n | 지정한 숫자만큼 화면 출력을 갱신한후 명 |
-u | 지정한 사용자의 프로세스를 모니터링 |
-b | 출력결과를 파일이나 다른 프로그램으로 전달 |
-d | 화면갱신주기를 초 단위로 설정 |
-p | 지정한 PID 프로세스를 모니터링 |
$ ps 명령어는 명령어가 실행된 순간의 프로세스 상태들에 대해서 정적인 정보만을 제공하며,
$ top 은 시스템 활동을 실시간으로 확인할 수 있다.
top 프로그램은 활동 순으로 나열된 프로세스들을 지속적으로 갱신하면서 보여준다.
위쪽은 시스템에 대한 전반적인 요약을 보여주며,
아래에 테이블로써 CPU 를 사용하는 순으로 프로세스들을 정렬해서 보여준다.
시스템 요약 부분 항목
첫째줄 - 현재시간, 서버가동 후 유지시간, 현재 접속 사용자, 최근 1, 5, 15분 동안 시스템 부하
둘째줄 - 프로세스의 상태(총 프로세스, 실행중, sleep, stop, 좀비프로세스)
셋째줄 - cpu 상태
넷째줄 - MEM 상태
다섯째줄 - swap메모리 상태
프로세스 cpu 사용 순서 부분 항목
PR - 우선순위
NI - Nice value(-20~19 사이의 숫자이며 값이 작을수록 우선순위가 높음)
VIRT - 작업에 사용된 가상 메모리 총사용량
RES - 프로세스가 사용하는 실제 메모리양
SHR - 프로세스가 사용하는 공유 메모리양
S - 현재 프로세스의 상태를 나타냄
TIME+ - 프로세스가 시작하여 사용한 CPU시간
top을 통해 모니터링 중인 상태에서 h 를 누르면 다양한 추가적인 기능들에 대한 도움말을 볼 수 있다.
top 역시 하나의 프로세스가 되기 때문에 top 의 결과에서 top 프로세스도 같이 등장하며, 시스템 리소스를 굉장히 적게 사용하기 때문에 시스템 부하를 적게 일으키는 좋은 프로그램이다.
최근에는 htop 이라는 조금 더 사용자에게 친화적인 도구를 사용하기도 한다.
프로세스 제어
시그널 - 프로세스 종료 (kill)
시그널은 프로세스 사이의 통신 수단인데 어떤 프로세스에 메시지를 보내 프로세스를 제어한다.
명령어를 실행함으로써 프로세스가 시작되고 그 프로세를 제어하기 위하여 사전에 정의된 시그널이 존재한다.
번호 | 시그널 | 의 미 |
1 | SIGHUP | 터미널에서 접속이 끊겼을때 보내지는 시그널, 변화된 내용을 적용하기 위해 재시작 할 때 사용된다. |
2 | SIGINT | 인터럽트 시그널로 실행을 중지시킴, Ctrl + c 입력시 보내지는 시그널 |
3 | SIGQUIT | 실행 중지 시그널로서 Ctrl + \ 입력시 보내지는 시그널 |
9 | SIGKILL | 프로세스를 강제로 종료 시키는 시그널 |
15 | SIGTERM | kill의 기본 시그널로 정상 종료 시키는 시그널 |
18 | SIGCONT | 시그널에 의해 정지된 프로세스를 다시 실행시키는 시그널 |
19 | SIGSTOP | 정지 시그널 |
20 | SIGTSTP | 일시정지 시키는 시그널로서 Ctrl + z 입력시 보내지는 시그널 |
위의 경우처럼 몇 가지 시그널이 존재하는데 불필요한 프로세스, 잘못 실행된 프로세스를 죽이는데 사용할 것은 KILL이있다.
kill 명령어는 프로세스를 강제로 종료시킨다. 좀비 프로세스나, 응답 없음, 비정상적으로 동작하는 프로세스들의 실행을 끝내게 해준다.
프로세스를 포어그라운드로 가져와서 ctrl + C 할 수도 있지만, PID 를 확인하여 kill 로 바로 종료시킬 수도 있다.
$ kill [options] [pid]
$ kill -9 PID # PID를 시그널 번호 9(KILL) 전송해서 죽임
$ kill -TERM -1 # 자신이 실행한 모든 프로세스를 종료
옵션 | 의미 |
-signal, -s signal | 지정한 시그널을 보냄 |
-l | 사용 가능한 시그널의 목록을 출력 |
프로세스 여러개 종료 (killall)
지정한 이름에 부합하는 모든 프로세스에게 시그널을 보낸다.
시그널을 지정하지 않으면 SIGTERM(15) 전송한다.
지정한 프로세스 이름에 매칭되는 프로세스가 모두 종료되므로 여러 프로세스를 띄우고 있는 데몬을 종료할 때 유용하다.
$ killall [option] [signal] 프로세스
옵션 | 의 미 |
-l | 시그널의 종류 출력 |
-s | 시그널의 이름을 지정하는 옵션 |
-v | 시그널 전송 결과를 출력 |
-w | 시그널을 받은 프로세스들이 종료 될때까지 대기 |
프로세스 필터 종료 (pkill)
프로세스 이름과 지정한 패턴이 부합하는 프로세스만을 종료
$ pkill [options] pattern
프로세스 전환 (foreground / background)
foreground : 보통 터미널에서 명령어를 입력하면 그 명령이 끝날때 까지 다른 명령어를 입력할 수가 없다.
이렇게 대화식으로 하나씩 주고 받게 되는데 이를 포어그라운드라고 생각하면 된다.
background : 반면 백그라운드는 명령어를 입력하면 다른 명령어도 실행이 가능하다.
백그라운드 의미에서 볼 수 있듯이 뒤에서 실행된다고 생각하면 된다. 물론 터미널이 닫히거나 로그아웃 될경우 종료 된다.
백그라운드 프로세스 출력 (jobs)
jobs 명령어는 현재 돌아가고 있는 백그라운드 프로세스 리스트를 모두 출력해준다.
백그라운드 프로세스는 스택처럼 쌓이는데,
+는 스택의 가장 위에 있다는 뜻이고
-는 바로 그다음 밑에 있다는 뜻이다.
$ jobs [options] [job name or number]
후면 처리 background processing (&)
명령어들을 후면에서 처리하고 전면에서는 다른 작업을 할 수 있으며 동시에 여러 작업을 수행할 수 있다.
백그라운드는 명령어의 맨 끝에 & 를 붙여 사용하면 후면 처리로 명령어가 실행된다.
$ (명령어;) & # 백그라운드 처리
# background에서 작업 실행하기
# 50초동안 sleep하라. 50초가 지나면 done1 과 done2 을 출력하라.
$ (sleep 50; echo done1) &
$ (sleep 50; echo done2) &
# 세미콜론은 연속해서 실행하라는 뜻
# 괄호는 두개 이상의 명령어를 연결하고 전체를 백그라운드에서 돌리기 위함
여기서 [1], [2]는 백그라운드 프로세스를 돌릴때마다 부여되는 job 번호를 의미한다.
2542, 2544는 프로세스 번호를 의미한다.
후면 처리로 전환 foreground -> background (bg)
포그라운드 프로세스를 백그라운드로 바꾸어주는 명령이다.
전면 실행중인 명령에서 Ctrl + z 를 누른후(일시정지) $ bg job번호 명령을 하달하면, 후면 처리가 됨을 볼 수 있다.
$ bg [job] # 포그라운드의 job을 백그라운드로 전환
만일 job 번호를 치지않고 그냥 $ bg 만 치면 jobs 목록에서 + 기호가 있는 job번호가 우선 실행하게 된다. (스택이 높기 때문에)
전면 처리로 전환 background -> foreground (fg)
백그라운드 프로세스를 포어그라운드 프로세스로 전환하는 명령어다.
$ fg [job] # 백그라운드에 멈춰있던 잡을 포어그라운드로 보내 셸 프롬프트상에서 다시 실행하는 명령어
# job번호를 생략하면, 스택에 제일 위에 있는 것이 foreground로 들어온다.
백그라운드 프로세스 일시정지 시키는 방법
백그라운드로 실행시킨 프로세스를 일시중지시키는 과정.
위에서 배운 전면 처리 전환 기법과 함께 쓰면 된다.
- & 를 사용해 백그라운드로 실행
- jobs 명령을 사용해 프로세스 번호 알아내고, fg 명령어를 실행해 프로세스를 포그라운드로 가져오기
- CTRL + Z 명령을 통해 포그라운드에서 프로세스 일시중지
프로세스 우선순위
프로세스 우선순위 변경 (nice)
프로세스의 우선순위를 의미하는 nice 값을 설정하는 원리 이다. (nice는 설정된 우선순위 값 NI)
위 강좌에서 $ ps -el 하면 나오는 프로세스 도표 헤더부에 NI 라는 항목이 바로 프로세스 우선순위 nice 값이다.
이 값은 사용자 프로세스 사이 우선순위를 조정할 수 있고 프로세스의 스케줄링에 영향을 줄수있다.
커다란 프로그램을 컴파일 할 때와 같이 CPU나 메모리를 많이 쓰게 될 경우, 시스템 속도를 저하시키기 떄문에 다른 프로세스에게 우선순위 값을 줄 때 사용한다.
[우선순위 NI 값 범위]
사용자가 지정할 수 있는 우선순위 값은 -20부터 19까지인데
값이 낮아야 우선순위가 높으므로, 가장 높은 우선순위는 -20이 되게 된다.
가장 높은 우선순위 NI 값 : -20
가장 낮은 우선순위 NI 값 : 19
기본적으로 주어지는 디폴트 값: 0
$ nice -n [NI값] [프로세스명] # 기존 우선순위 값에 N만큼 더한 우선순위로 [프로세스명]을 실행시킨다.
$ nice [프로세스명] # -n 옵션 없이 사용할 경우 N값은 디폴트로 10을 갖는다. 즉 10을 더해 우선순위를 낮춰서 실행시키는 것
$ nice -[NI값] 프로세스명 # nice -n N 한 것과 동일. NI값만큼 증가
$ nice --[NI값] 프로세스명 # NI값만큼 감소
참고로 우선순위를 높이는 것은 root 관리자 계정만 가능하다
- ps -l 로 실행중인 bash 우선순위 값을 확인. PID가 2030인 bash의 PRI는 80, NI 값은 0 임을 알 수있다.
- 여기서 nice -n 15 bash 명령어를 실행하면, 기존 우선순위값인 0에서 15를 더한 15 NI로 bash를 실행시키게 한다.이때 nice는 실행 중인 프로세스의 우선순위를 변경하는 게 아니기 때문에 기존 bash PID 2030과는 다른 새로운 2037 pid의 bash가 실행되게 된다.
- 우선순위를 높이는 것은 root 관리자 계정만 가능하기 때문에 sudo로 --14(14증가)를 실행한다
- NI값이 15에서 1로 변함을 알 수있다. (마찬가지로 nice는 현재 실행중인 프로세스를 바로 변경시키는게 아니라, 우선순위를 변경한 새로운 프로세스를 생성하는 식이라, PID가 다르다)
nice 명령어의 우선순의 숫자 조절 연산은, 대시(-) 하나는 증가, 두개(--)는 감소 다.
실행중인 프로세스 우선순위 변경 (renice)
현재 실행중인 프로세스의 nice값을 변경한다.
nice는 프로세스명으로 우선순위를 조정하고, 명령을 실행하면 새로운 프로세스가 발생하지만,
renice는 PID로 우선순위를 조정하고 기존의 프로세스 우선순위 값을 추가없이 바로 수정한다
$ renice [옵션] [변경할 NI값] [PID]
옵션 | 의미 |
-n | nice와 마찬가지로 우선순위를 조정할 때 사용 |
-g | 특정 그룹을 지정해서 우선순위를 조정할때 사용합 |
-p (--pid) | 디폴트 값이기 때문에 옵션 안붙이고 renice N pid 이렇게 쓰셔도 됩니다. renice N -p pid 와 동일 |
-u (--user) | 특정 사용자를 지정해서 우선순위를 조정 |
nice 명령어를 썼던 위와 달리, renice 명령어는 PID가 변경되지않고 똑같음을 알 수 있다.
프로세스 유지 (nohup)
일반적으로 시스템에서 로그아웃하면 로그아웃한 세션과 연관된 모든 프로세스에게 HUP 시그널(1)을 보내서관련된 모든 프로세스는 자동으로 종료되지만,
nohup을 사용하면 해당 시그널을 가로채 무시하기 때문에 로그아웃하더라도 프로세스를 계속 실행되게 된다.
즉, 사용자가 로그아웃해도 실행중인 프로세스를 백그라운드로 유지시켜주는 명령어 이다.
$ nohup command
프로세스 검색 (pgrep)
지정한 패턴과 일치하는 프로세스의 정보를 출력한다.
파일 패턴 검색 명령어인 grep 명령어의 프로세스 버젼이라고 보면된다.
옵션 | 의미 |
-x | 패턴과 정확히 일치하는 프로세스 정보 출력 |
-n | 패턴을 포함하는 가장 최근의 프로세스 정보 출력 |
-u 사용자 이름 | 특정 사용자에 대한 모든 프로세스 출력 |
-l 프로세스명 | PID와 프로세스 이름 출력 |
-t term | 특정 단말기와 관련된 프로세스 정보 출력 |
$ pgrep [options] [pattern]
# root사용자가 실행한 bash 프로세스 정보를 확인
$ pgrep -l bash -u root
# 참고자료
http://www.incodom.kr/Linux/%EA%B8%B0%EB%B3%B8%EB%AA%85%EB%A0%B9%EC%96%B4/process
이 글이 좋으셨다면 구독 & 좋아요
여러분의 구독과 좋아요는
저자에게 큰 힘이 됩니다.