티스토리 뷰

Study/Linux

[Linux] Processes (1)

생각많은 소심남 2016. 7. 28. 21:56

Process에 대해서는 이전 포스트들에서도 많이 다룬 내용이니, 이번 포스트에서는 Linux 관점에서의 Process에 대해서 언급해보고자 한다.

 

 Linux에서의 Process 중 가장 먼저 실행되는 process는 Init이고 process ID는 1을 가리킨다. Init Process는 System이 부팅되고 난 후, 제일 처음으로 실행되는 Process이기도 하고, System 종료시점까지 가장 마지막으로 숭해되는 Process이기도 하다. 보통 Init이 실행되고 난 후에 시스템에서 필요한 Process는 Init에서 파생되어서 나오는데, 이 Init과 파생되어 나온 Process 간의 관계를 흔히 부모-자식 관계라고 표현한다. 물론 파생되어서 나온 Process에서 생성된 Process 간에도 이런 관계가 성립하며, 이때문에 Init Process를 ancestor(조상) process 라고 말할 수도 있다.

 사실 Process의 life cycle을 살펴보면 이런 부모 자식 관계와 유사함을 볼 수 있다.

 - 자식 Process는 항상 부모 Process에게서 모든 정보를 상속받는다. 그래서 fork()를 통해 자식 process를 생성했을 때도 부모의 코드 영역을 그대로 가져와서 사용한다. 단 Process ID(PID)와 Parent Process ID(PPID)값이 다르기 때문에 이를 바탕으로 코드 내에서, 코드를 수행하고 있는 Process가 부모인지 자식인지를 구분한다.

 

 - 부모 Process는 항상 자식 Process가 끝날때까지 기다린다. 즉, 자식이 일을 마치면서 자식이 가진 PID를 반환하는데, 이 값을 받기 전까지 부모 Process는 계속 대기한다. 참고로 외부 요인에 의해서 자식 Process가 먼저 종료되는 case가 있을 수 있다. 보통 이렇게 종료되는 경우 process는 현재 상황에 따른 exit code를 반환하게 되는데, 이 exit code에 따라서 현재 수행되고 있는 process의 table list에서 제거되지 않을 수 있다. 즉, 자식 Process는 종료되었는데, 부모 Process는 자식 Process가 살아있다고 여기는 것이다. 이럴 때의 자식 Process를 zombie(defunct) process라고 한다.

 

 - 반대로 자식 Process보다 부모 Process가 먼저 종료되는 케이스도 존재한다. 부모를 잃은 자식 Process에 대한 표현도 Orphan(고아) Process 라고 한다.

 

 - Init Process는 Ancestor Process인데, 위와 같이 Orphan Process가 발생하는 경우 해당 Process의 부모가 되어준다. 그래서 이때 Orphan Process의 PPID는 1로 바뀐다. (최근에는 좀 바뀌었다. systemd에 의해서 수행되는 Linux의 경우는 이런 경우 Orphan Process의 PPID가 2로 바뀐다.) 좀 표현은 이상한데, 이런 Init Process를 Zombie killer 나 child reaper? 자식 학살자로 표현하는 데도 있다.

 

이런 계층적 구조의 형태는 terminal에서 다음 명령어를 쳐보면 확인해볼 수 있다.

 

$ ps axjf

   0     1     1     1 ?           -1 Ss       0   0:25 /sbin/init
    1   739   738   738 ?           -1 S        0   0:00 upstart-udev-bridge --daemon
    1   741   741   741 ?           -1 Ss       0   0:00 /sbin/udevd --daemon
  741  1173   741   741 ?           -1 S        0   0:00  \_ /sbin/udevd --daemon
  741  1174   741   741 ?           -1 S        0   0:00  \_ /sbin/udevd --daemon
    1   867   867   867 ?           -1 Ss       0   0:42 rpcbind -w
    1  1033  1033  1033 ?           -1 Ss     116   0:00 rpc.statd -L
    1  1384  1383  1383 ?           -1 S        0   0:00 upstart-socket-bridge --daemon
    1  1471  1471  1471 ?           -1 Ss       0   0:03 smbd -F
 1471  1692  1471  1471 ?           -1 S        0   0:16  \_ smbd -F
 1471 26061  1471  1471 ?           -1 S        0   5:09  \_ smbd -F
 1471  2011  1471  1471 ?           -1 S        0   0:14  \_ smbd -F
 1471 10557  1471  1471 ?           -1 S        0   0:00  \_ smbd -F
 1471 29477  1471  1471 ?           -1 S        0   0:00  \_ smbd -F
 1471 31313  1471  1471 ?           -1 S        0   0:00  \_ smbd -F
    1  1484  1484  1484 ?           -1 Ss       0   0:00 /usr/sbin/sshd -D
 1484 13866 13866 13866 ?           -1 Ss       0   0:00  \_ sshd: chanseok.kang [priv]
13866 14378 13866 13866 ?           -1 S     1033   0:12  |   \_ sshd: chanseok.kang@pts/0
14378 14379 14379 14379 pts/0     5429 Ss    1033   0:00  |       \_ -bash
14379  5429  5429 14379 pts/0     5429 Sl+   1033   1:19  |           \_ vi kernel/drivers/tty/serial/test_uart.c
 

 

 

 

참고로 PID로 정의할 수 있는 숫자를 확인하는 방법은 아래와 같이 알수 있다.

 

$ cat /proc/sys/kernel/pid_max
32768

 

이 값은 사실 16bit로 표현하면 0xFFFF인데, 아마 이 PID를 표현하는 필드가 16bit으로 제한되어 있다보니 이렇게 제한을 두지 않았을까 하는 생각이 든다. 그러면 만약 Process가 32768보다 더 많이 생성되면 어떻게 될까? 이 때는 PID가 다시 300번대로 다시 정의된다.

댓글