4.3 프로세스 제어    [gdoc]

쉘에서는 프로세스를 작업(job)이라는 단위로 관리하는데 작업은 포그라운드 (foreground)백그라운드 (background) 두 가지 방식으로 동작한다. 포그라운드는 작업이 시작되고 종료되는 시점까지 다른 쉘 명령어를 수행할 수 없고 대기하는 방식을 말한다. 반면 백그라운드로 작업을 수행하면 동시에 다른 명령어들을 실행시킬 수 있다. 이렇게 동시에 여러 명령어들을 실행시키는 것을 멀티태스킹(multi-tasking)이라고 한다.


쉘에서 작업을  제어하기 위한 명령어들을 다음 표에 정리하였다. 아래 표에서 JID는 jobs 명령으로 확인할 수 있는 작업의 고유 번호이다.


문법

동작

비고

실행명령 &

실행명령을 백그라운드에서 수행한다.


ps

프로세스의 리스트(전 절 참조)


jobs

백그라운드 프로세스 리스트


CTRL-Z

포그라운드 작업을 일시 중지한 후 백그라운드로 밀어 넣는다.


CTRL-C

포그라운드 작업을 정지(종료)


%JID

백그라운드 프로세스는 고유번호(JID)가 매겨지는데 (fg, bg, kill 명령에서) 그것을 참조하기 위해서 번호 앞에 %를 붙인다.


fg %JID

백그라운드 작업을 포그라운드로 올린다.


bg %JID

일시 정지된 백그라운드 작업을 재시작


kill PID / %JID

kill -KILL PID / %JID

kill -STOP PID / %JID

kill -CONT OID / %JID

프로세스를 종료.

프로세스 강제  종료 (kill -9 PID)

백그라운드 프로세스 실행 일시 정지

정지된 백그라운드 프로세스 재시작




bg %JID

pkill CMD

명령어(CMD)로 실행된 프로세스 종료



어떤 명령을 처음부터 백그라운드로 실행하고자 한다면 끝에 ‘&’를 붙이면 된다.


pi@raspberrypi:~ $ sleep 100&

이렇게 하면 ‘sleep 100’ 명령은 즉시 백그라운드  실행 모드로 들어가고 쉘에서 다른 일을 처리할 수 있다.

jobs는 백그라운드 프로세스 리스트를 표시하는 명령어이다.


pi@raspberrypi:~ $ jobs
[1]-  Running                 sleep 100 &
[2]+  Running                 sleep 200 &

리스트의 맨 앞의 숫자가 작업의 고유 번호(JID)이고 그 다음 실행여부(Running/Stopped)가 표시되며 실행한 명령어가 이어서 나타난다.

포그라운드 작업은 ctrl+c를 누르면 대부분 종료된다. ctrl+c는 인터럽트 신호를 포그라운드 작업에 전달한다. 프로세스는 기본적으로 인터럽트 신호를 받으면 종료하도록 되어있다.


만약 포그라운드에서 어떤 작업을 수행중에 ctrl-z를 누르면 중지되고 쉘로 빠져나오게 된다. 이럴 때 jobs 명령어로 확인하면 Stopped 로 표시되고 이 작업을 백그라운드에서 재시작하려면 bg 명령을 내리면 된다.


pi@raspberrypi:~ $ sleep 200
^Z
[1]+  Stopped                 sleep 200
pi@raspberrypi:~ $ jobs
[1]+  Stopped                 sleep 200
pi@raspberrypi:~ $ bg %1
[1]+ sleep 200 &
pi@raspberrypi:~ $ jobs
[1]+  Running                 sleep 200 &
pi@raspberrypi:~ $ kill -STOP %1
[1]+  Stopped                 sleep 200

위에서 보듯이 정지된 백그라운드 프로세스를 백그라운드 상태에서 다시 시작하려면
‘kill -STOP %N’명령을 주면 된다.

프로세스를 정상적으로 종료하기 위해서는 ‘kill’ 명령을 이용하면 된다. 그리고 좀비 프로세스를 강제로 종료하기 위해서는 ‘kill -KILL’ 을 이용하면 된다.

Posted by 살레시오
,

4.2 프로세스 목록 확인   [gdoc]

ps 명령어로 프로세스의 목록을 확인할 수 있다.


~$ ps


아무런 옵션을 주지 않으면 현재 터미널에 관련된 프로세스들의 간략한 정보를 보여준다.  좀 더 자세한 정보를 알고 싶다면 -f 를 붙인다.


~$ ps -f


시스템의 모든 프로세스 리스트를 보고 싶다면 -e 옵션을 주면 된다.

~$ ps -e

~$ ps -ef


여기에서 알아두어야 할 개념들은 다음과 같다.


[표] ps -f 명령으로 나타나는 항목들의 의미

항목

의미

UID

프로세스의 실행/소유자 아이디

PID

프로세스의 고유 번호(Process Identification Number)

PPID

부모 프로세스의 PID (Parent PID)

C

프로세스 우선순위

STIME

프로세스가 시작된 시간

TTY

프로세스와 연결된 터미널

TIME

실행에 걸린 시간

CMD

프로세스를 생성하는데 내린 명령


만약 모든 프로세스의 트리를 보고 싶다면 pstree 명령을 내리면 된다.


pi@raspberrypi:~ $ pstree
systemd─┬─ModemManager─┬─{gdbus}
       │              └─{gmain}
       ├─avahi-daemon───avahi-daemon
       ├─bluetoothd
       ├─

이것을 보면 systemd(PID:1)프로세스가 모든 프로세스의 부모(조상)이라는 것을 알 수 있다.

top 명령은 주기적을 현재 실행중인 프로세스의 목록을 보여준다. ps, pstree 명령과 달리 CPU나 메모리 점유율이 높은 프로세스이 순으로 정렬해서 보여주며 주기적으로 최신 정보로 갱신해 준다.


pi@raspberrypi:~ $ top
top - 21:59:46 up 44 min,  3 users,  load average: 0.00, 0.06, 0.14
Tasks: 170 total,   1 running, 169 sleeping,   0 stopped,   0 zombie
%Cpu(s):  3.1 us,  0.8 sy,  0.0 ni, 96.1 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
KiB Mem:    947740 total,   662164 used,   285576 free,    23600 buffers
KiB Swap:   102396 total,        0 used,   102396 free.   362252 cached Mem

 PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND
 680 root      20   0  140504  50124  29596 S   1.7  5.3   0:48.91 Xorg
1091 pi        20   0    5740   2648   2180 S   1.0  0.3   0:23.97 top
1352 pi        20   0    5592   2488   2124 S   1.0  0.3   0:17.16 top

이 결과에서 보면 Xorg 프로세스가 시스템 자원을 가장 많이 사용하고 있다는 것을 알 수 있다.

Posted by 살레시오
,

리눅스 프로세스(process)란   [gdoc]

프로세스(prcess)란 현재 실행 중인 프로그램을 의미한다. 리눅스는 여러 개의 프로그램을 동시에 실행할 수 있으며 이것을 다중실행(multi-tasking)이라고 한다.


하나의 명령이 실행하기 위해서 하나 또는 여러 개의 프로세스가 생성되어 수행된다. 프로세스 간에는 부모-자식 관계가 있는데 부모가 자식을 생성하고 자식이 또 자신의 자식을 생성하는 등 프로세스들 사이에 트리(tree) 관계가 형성한다. 예를 들어 쉘이 실행되면 이 자체로 프로세스이고 쉘 안에서  명령이 실행되면 쉘-프로세스의 자식 프로세스가 생성된다.


프로세스들은 각기 고유한 번호가 있으며 이를 PID(Process Identification Number)라고 한다. 데비안 리눅스가 부팅될 때에는 모든 프로세스의 최상위 프로세스인 systemd (PID는 1)이 생성되고 모든 프로세스들은  이 1번 프로세스의 자식 프로세스들이다. 부모 프로세스의 PID를 줄여서 PPID라고 한다.


프로세스를 분류하면 데몬(daemon), 자동 프로세스, 상호작용 프로세스  등으로 분류할 수 있다.

4.1.1 데몬(daemon)

데몬은 항상 백그라운드로 실행되는 프로세스이며 대부분 부팅시에 자동으로 시작된다. 데몬은 평수에 대기 상태로 서비스 요청을 기다리다가 요청이 들어오면 해당 서비스를 제공한다. 프로세스이름 끝에 보통 ‘d’가 붙어있으며 예를 들면 네트워킹 데몬인 xinetd 이다. 이 프로세스는 부팅시에 실행되고 백그라운드에서 대기하다가 ftp 클라이언트 같은 네트워크 프로그램이 연결을 요구할 때까지 기다린다.

4.1.2 자동 프로세스

자동 혹은 배치(batch) 프로세스는 터미널과 연결되어 있지는 않고 스풀러(spooler)영역에 순서대로 저장되어 저장된 순서대로 실행을 기다리는 프로세스이다. 이 프로세스는 다음과 같이 두 경우에 실행된다.

  • 특정 날짜/시간에 at 명령을 이용하여 실행된다.

  • 시스템 자원이 실행하기에 충분한 경우 batch 명령에 의해 실행된다.

4.1.3 상호작용 프로세스

이것은 터미널에서 시작되고 제어되는 프로세스로서 시스템에 접속한 사용자가 상호작용 프로세스를 시작하게 된다. 즉, 자동으로 시스템에서 실행되지 않는 프로세스이다. 포그라운드에서 실행되는 동안은 다른 프로그램을 실행할 수 없다. 또한 백그라운드로 실행을 밀어 넣을 수도 있으며 백그라운드에서 실행되는 동안에 터미널에 다른 명령을 입력할 수 있다.  


less 명령을 실행한 경우 less가 시작된 이후에는 터미널의 입력은 less로 전달되며 정해진 명령만이 less에서 효과를 발휘하고 나머지는 무시된다. 하지만 백그라운드로 밀어 넣는다면 less명령이 여전히 수행되고 있는 동안에도 다른 작업을 수행할 입력이 가능해진다.


쉘은 ‘job control’ 기능을 제공하며 이것을 이용하면 사용자는 여러 개의 프로세스를 제어할 수 있다. 특정 프로세스를 포그라운드 혹은 백그라운드로 지정할 수 있으며 실행을 멈출 수도 있고 재시작할 수도 있다.


백그라운드에서 프로세스를 실행하는 경우는 사용자 입력이 필요치 않으면서 시간이 오래 걸리는 일을 수행할 때 유용하다. (GUI환경에서는 터미널을 얼마든지 더 열 수 있으므로 큰 의미가 없을 수 있다.) 백그라운드로 명령을 실행하고자 할 경우 명령어 끝에 ‘&’를 붙인다.


~$ sleep 100 &
~$ _

이 명령은 sleep 100을 백그라운드에서 수행하라는 것이다. 따라서 그 즉시로 다른 명령을 내릴 수 있다.

4.1.4 부모 프로세스 / 자식 프로세스

어떤 프로세스가 실행 도중에 자식 프로세스를 생성할 수 있다. 자식 프로세스는 작업이 끝나면 부모 프로세스에게 결과를 돌려주고 종료된다. 모든 프로세스의 조상 프로세스는 1번 (systemd) 프로세스이다.

4.1.5 고아 프로세스 /좀비 프로세스

고아프로세스는 자식 프로세스가 종료되지 않았는데 부모 프로세스가 종료된 경우 생성된다. 이경우 1번 프로세스가 그 자식프로세스를 승계하여 고아 프로세스를 종료할 수 있도록 해준다.

좀비 프로세스는 실제 동작이 종료되었는데도 동작 중인 프로세스 목록에 자리를 차지하고 있는 경우이다. 자식 프로세스의 종료 신호를 부모 프로세스가 제대로 처리하지 않은 경우에 발생한다. 잘못 작성된 프로그램으로 인해서 좀비 프로세스가 증가한다면 프로세스 테이블이 꽉 차게 되어 다른 정상 프로세스의 동작에 영향을 줄 수도 있다.

Posted by 살레시오
,