강좌
클라우드/리눅스에 관한 강좌입니다.
자격증 분류

리눅스마스터1급 : 리눅스프로세스(process)

작성자 정보

  • 관리자 작성
  • 작성일

컨텐츠 정보

본문

리눅스마스터1: 리눅스프로세스(process)

 





일반적으로 사용자가 컴퓨터에서 실행시키기 위하여 작성한 프로그램(컴파일 및 링크가 모두 완료된 실행 프로그램 또는 실행 파일)과 이 프로그램의 실행에 필요한 입력 데이터를 묶어서 작업(job)이라 하는데, 작업은 컴퓨터에 실행 의뢰되기 전의 상태 또는 실행 의뢰되는 과정에서 사용하는 용어라 할 수 있다.

 

 

 

 

그리고 이러한 작업이 컴퓨터 시스템에 실행 의뢰되어 운영체제, 즉 커널에서 이 사실이 전달되면 이 작업은 커널에 등록되며 이와 같이 커널에 등록된 작업을 프로세스라 부른다.

 

 

 

 

, 프로세스란 커널에 등록되어 커널의 관리 하에 있는 작업을 의미하며, 이를 일반적으로 실행중인 프로그램 또는 실행중인 작업이라 정의하고 있다.

 

 

 

 

그러나 프로세스의 정확한 정의 내지는 특성을 이해하기 위해서는 보다 세부적인 이해가 필요하다.

 

 

 

 

 

 

컴퓨터 시스템에 입력된, 즉 커널에 등록된 프로세스는 자신이 실행해야 할 프로그램을 가지고 있다.

 

 

 

 

이 프로그램을 실행시키기 위하여 프로세스는 커널에게 각종 자원(resource)들을 요청하게 된다.

 

 

 

 

여기서 자원이란 기억 장치, 프로세서, 디스크 등의 각종 하드웨어 장치나 메시지, 파일 등의 소프트웨어 요소들을 의미한다.

 

 

 

 

다시 말하면, 프로세스는 자신이 실행해야 할 프로그램이나 이와 관련된 데이터를 기억 장치에 적재시키기 위하여 기억 장치를 요구할 것이며, 이를 실행시키기 위하여 프로세서도 요구할 것이다.

 

 

 

 

또한 프로그램이 실행되는 동안 필요한 디스크 파일들에 접근하기 위하여 각종 파일들을 요구할 수도 있다.

 

 

 

 

이와 같은 관점에서 프로세스를 정의할 때 좁게는 프로세서를 할당받을 수 있는 개체(entity), 넓게는 컴퓨터 시스템 내의 각종 자원들을 요구하고 할당받을 수 있는 개체로 정의하기도 한다.

 

 

 

 

또한 커널은 프로세스를 관리하기 위하여 커널 공간(kernel space)내에 각 프로세스들에 대한 정보를 저장하고 사용한다.

 

 

 

 

이와 같이 커널에 등록된 각 프로세스들에 대한 정보를 저장하고 있는 영역을 프로세스 관리 블록(PCB ; Process Control Block)이라 하는데, 프로세스를 이와 같이 PCB를 할당받는 개체로 정의하기도 한다.

 

 

 

 

지금까지 언급한 설명들을 종합하면 프로세스는 다음의 여러 가지 형태로 정의될 수 있음을 알 수 있다.

 

 

 

실행중인 프로그램(작업)

 

커널에 등록되고 커널의 관리 하에 있는 작업

 

각종 자원들을 요청하고 할당받을 수 있는 개체

 

프로세스 관리 블록을 할당받는 개체

 

 

 

 

프로세스 자원의 개념

 

컴퓨터 시스템 내에서 프로세스는 스스로 움직이는(프로그램이 실행되는 것을 이와 같이 표현한다.) 능동적인 개체인데 비하여, 자원이란 커널에 의해 다른 주체에게 할당되고 이의 사용이 끝날 경우 다시 반납되는 피동적인 개체에 해당한다.

 

 

 

 

 

 

하드웨어 자원은 기억 장치나 프로세서, 하드 디스크, 자기 테이프, 단말기, 모니터, 키보드 등의 각종 하드웨어 장치들을 의미하며, 소프트웨어 자원은 메시지, 시그널(signal), 파일, 각종 공유 소프트웨어 등을 의미한다고 할 수 있다.

 

 

 

 

프로세스는 실행중에 각종 자원들을 요구하기도 하고 이를 할당받기도 하며, 사용이 끝났을 때에는 반납하기도 하면서 진행한다.

 

 

 

 

이에 따라 컴퓨터 시스템의 상태를 각종 프로세스들과 각종 자원들의 상호 작용(interaction)으로 모델링하기도 한다.

 

 

 

프로세스 관리 블록

 

 

컴퓨터 시스템 내의 프로세스들은 모두 커널 공간에 자신의 PCB를 하나씩 갖게 되며 이의 관리는 커널이 하게 된다.

 

 

 

 

 

 

다르게 설명하면 커널은 자신에게 등록된 프로세스들을 관리하기 위하여 프로세스마다 하나씩의 PCB를 할당해 주고, 이 영역에 해당 프로세스에 대한 각종 정보들을 저장하여 프로세스를 관리할 때 사용한다.

 

 

 

 

PCB에 저장되는 프로세스 관련 정보들은 운영체제마다 조금씩 다를 수 있지만 일반적으로는 다음과 같은 정보들을 PCB에 유지하게 된다.

 

 

 

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

 

 

프로세스의 우선순위(priority)

 

 

프로세스의 현재 상태(current state)

 

 

프로세스가 할당받은 자원들의 리스트 또는 이들에 대한 포인터

 

문맥 저장 영역(context save area)

 

 

 

 

 

 

여기서 프로세스의 고유 번호는 커널이 시스템 내의 프로세스들을 관리하는 데 있어서의 편리성을 위하여 프로세스마다 다르게 부여되는 번호이며 이는 프로세스가 생성될 때에 부여된다.

 

 

 

프로세스의 우선순위는 프로세스 스케줄링에서 사용하기 위한 정보이며, 특히 운영체제가 우선순위 기반 스케줄링(priority-based scheduling)을 하는 경우에 필요한 정보이다.

 

 

 

 

커널은 여러 프로세스들 중 프로세서를 할당할 프로세스를 선정하기 위해 이 우선순위를 참조할 수 있다.

 

 

 

 

 

 

커널에 등록된 프로세스들이 각각 어떤 자원들을 할당받고 있고 어떠한 상황에 있는가에 따라 프로세스 상태를 구분할 수 있는데, 이에 대한 정보가 프로세스 현재 상태 필드에 저장되며 프로세스의 상태가 변화할 경우 커널은 이 필드의 정보를 갱신하게 된다.

 

 

 

 

 

 

위에서 언급한 PCB4번째 영역은 프로세스가 현재 어떤 자원들을 할당받고 있는지에 대해 항상 커널이 알 수 있도록 프로세스가 할당받은 자원들에 대한 정보를 저장해 두는 영역이다.

 

 

 

 

커널은 이 영역을 참조함으로써 시스템 내의 어느 자원이 어느 프로세스에게 할당되어 있는지를 알 수 있으며 이를 자원의 관리에 참고하고 사용할 수 있다.

 

 

 

 

마지막으로 문맥 저장 영역은 프로세스가 실행 도중 어떤 이유로 인하여 실행을 중지해야 할 경우 프로세스가 프로세서의 각종 레지스터(registers)들에 저장하여 갖고 있던 값들(이를 일반적으로 레지스터 문맥(register context)이라 한다.)을 보존하기 위하여 사용된다.

 

 

 

 

 

 

실행중이던 프로세스가 중지되면 다른 프로세스가 프로세서를 할당받게 되는데 이때 기존 프로세스가 사용하던 프로세서 내의 각종 정보들이 소멸될 우려가 있으며, 따라서 이를 보존하기 위하여 레지스터 문맥을 기억 장치의 커널 공간 중 해당 프로세스의 PCB 영역 내에 저장하는 것이다.

 

 

 

 

, 실행중인 프로세스가 중지될 때에는 레지스터 문맥을 PCB 영역 내에 저장하게 되며, 이 프로세스가 다시 실행될 때에는 직전에 이 영역에 저장되었던 내용들을 다시 프로세서 내의 레지스터들에 되돌려 놓게 된다.

 

 

 

 

이 외에도 PCB에 저장되어야 할 정보들은 매우 많으며, 이는 운영체제에 따라 서로 다르다.

 

 

 

 

예를 들어 Unix 운영체제에서는 PCB 영역을 프로세스 테이블 슬롯(process table slot) 영역과 u-area라 부르는 영역으로 나누어 운영하고 있으며, 프로세스에 대한 정보 중 커널에 항상 필요한 정보들은 프로세스 테이블 슬롯에 저장하고 실행중인 프로세스에 대해서만 필요로 하는 정보들은 u-area에 저장하여 이를 관리한다.

 

 

 

 

 

 

커널이 시스템 관리, 특히 프로세스 관리의 목적으로 PCB영역을 참조하는 빈도는 대단히 높다.

 

 

 

 

결국 커널의 PCB영역 참조 및 갱신 속도를 빠르게 하는 것은 시스템 전체의 성능에 많은 영향을 미칠 것이며, 따라서 시스템의 성능을 높이기 위해서는 이를 위한 기법이 필요하다.

 

 

 

 

일반적으로는 PCB의 내용을 참조, 갱신하는 기계어 명령을 두거나 각 PCB의 주소를 프로세서 내에서 유지하게 하는 기법을 사용한다.

 

 

 

프로세스 식별자(PID)

 

 

PIDProcess IDentifier로 프로세스 식별자라 하며 유닉스 커널과 같은 운영체계에서 각 프로세스나 서비스를 식별하기 위해 할당하는 고유한 번호이다.

 

 

 

 

PID“fork”라는 시스템 호출에 의해 반환되며, 주어진 프로세스에 어떤 행동을 이행하기 위해 wait()이나 kill() 등에 전달될 수 있다.

 

 

 

 

 

 

리눅스의 사용자가 하나의 명령어를 사용하기 위해 쉘 프롬프트에서 사용하고자 하는 어떤 명령을 입력하고 엔터를 치면 쉘(쉘은 유닉스에서 대화형 사용자 인터페이스를 부르는 용어)은 그 이름이 먼저 쉘에서 제공하는 내부 명령인지 확인하고, 내부 명령으로 확인이 된다면 그것을 자체적으로 실행한다.

 

 

 

 

하지만 내부 명령이 아니라면 먼저 PATH 환경 변수에 지정된 디렉토리를 검색해서 그 파일이 있는지 확인을 한 뒤 만약 그것이 있다면 그 파일을 실행하도록 커널에게 지시한다.

 

 

 

 

 

 

그러면 커널은 그 파일의 접근 권한과 사용자를 비교해서 실행 권한이 있는 지 없는 지 확인한 후 없다면 사용할 수 없음을 쉘에 보낸다.

 

 

 

 

그런데 비교해서 확인한 후 실행할 수 있다면 먼저 그 실행 파일의 내용을 메모리에 불러들이는 동시에 고유의 번호를 붙이는데, 이것을 앞서 언급한 프로세스 식별 번호(Process IDentity number - PID 번호)라고 한다.

 

 

 

 

 

 

이제 실행되고 있는 하나의 파일은 프로세스라고 한다는 것을 알고 있다.

 

 

 

 

이 번호는 각 프로세스들의 시작 순서에 따라 차례로 붙여진다.

 

 

 

 

이 번호는 커널 측면에서 본다면 프로세스 관리에, 즉 다중 작업에 관계가 있다.

 

 

 

 

다시 말하자면 프로세스 식별 번호(PID 번호)는 사용자 측면에서 본다면 프로세스 중지 명령에서 사용된다.

 

 

 

 

시그널

 

리눅스는 사용자 또는 프로그램이 프로세스를 제어할 수 있도록 시그널(Signal), 즉 신호를 지원한다.

 

 

사용자 또는 프로그램은 이 시그널을 통해 특정한 프로세스에 어떤 행위를 하도록 지시한다.

 

 

리눅스는 signal.h를 포함하는 커널 헤더에 시그널과 관련한 다양한 정의와 함수를 제공하는데, 다음은 시그널과 관련된 헤더 파일의 예이다.

 

 

 

/usr/include/linux/signal.h (아래 두 파일을 인용(include))

 

/usr/include/asm/signal.h : 다양한 시그널을 정의

 

/usr/include/asm/siginfo.h (아래 파일을 인용(include))

 

/usr/include/asm-generic/siginfo.h : 시그널에 관한 함수와 정의를 포함

 

/usr/include/linux/time.h : 시그널에 관한 함수와 정의를 포함

 

 

 

 

리눅스에서는 kill, POSIX.1b signals, POSIX.1b timers, SIGCHLD 등에 의해 시그널이 발생하는데, 리눅스 시스템의 사용자는 kill 명령을 통해 시그널을 보낼 수 있고 이에 따라 프로세스의 제어가 가능하다.

 

 

 

 

 

kill 명령어에 의해 보낼 수 있는 시그널의 종류는 다음과 같다(kill 명령어에 대한 상세한 사항은 제4장에서 상세히 다루도록 한다).

 

 

 

cd748e8935a013f3cf536af9b9b6806b_1683618163_8981.png
 

 

 

 

부모와 자식 프로세스

 

특정한 프로세스에 종속된 프로세스는 해당 프로세스의 자식 프로세스(child process)라고 한다.

 

 

 

 

그리고 그 특정한 프로세스는 자식 프로세스에 대해 부모 프로세스(parent process)가 된다.

 

 

 

 

이런 의미에서 리눅스 운영체제에서 PID 번호가 1init는 모든 프로세스의 부모 프로세스이다.

 

 

 

 

 

 

물론, PID 번호가 0스와퍼(swapper)라는 프로세스가 있기는 하지만 이 스와퍼라는 프로세스는 부팅되면서 잠시 실행되었다가 init 프로세스를 실행시킨 후에 몇 가지 역할을 수행하고 부팅이 완료되면 종료된다.

 

 

 

 

 

 

그리고 부팅 중에 스와퍼에 의해 실행된 init 프로세스는 부팅 후에도 PID 1번으로 계속 남아 있다.

 

 

 

 

init 프로세스가 생성된 이후에 시스템에서 생성되는 모든 프로세스들은 PID1번인 init 프로세스에 의해서 실행되고 이에 종속된다(init는 기본적으로 /etc/inittab 파일을 읽어 들여서 그 설정에 따라 각 실행레벨(runlevel)에 포함된 스크립트를 실행하고 사용자들이 로그인할 수 있도록 getty 프로그램을 실행한다).

 

 

이런 이유에서 init가 모든 프로세스의 부모 프로세스라고 하는 것이다.

 

 

 

 

이러한 프로세스들의 생성 가계도를 확인해 보려면 pstree 명령어를 실행해 보면 된다.

 

 

 

 

이 명령어는 프로세스들을 트리(tree) 구조로 출력하며, 이 트리 구조의 최상단에 위치한 것이 init이다.

 

 

 

 

한편, 부모 프로세스에 종속되어 있는 자식 프로세스는 대부분 부모 프로세스가 종료하면 자동으로 함께 종료된다.

 

 

 

 

그런데 부모 프로세스가 종료된 후에도 자식 프로세스가 아직 남아 있는 경우가 있는데, 이런 상태의 프로세스를 좀비 프로세스(zombie process)라고 한다.

 

 

 

 

이런 좀비 프로세스가 많아지면 시스템이 느려지는 원인이 될 수 있다.

 

 

 

 

대부분의 좀비 프로세스는 init 프로세스에 의해 관리가 되는데, 계속 살아 있는 좀비 프로세스가 있다면 kill 명령에 의해 강제로 종료시키는 것이 가능하다.

 

 

 

 

만약 시스템이 재부팅하면 이런 좀비 프로세스는 자동 제거된다.

 

 

 

관련자료

댓글 0
등록된 댓글이 없습니다.

공지사항


뉴스광장


  • 현재 회원수 :  60,056 명
  • 현재 강좌수 :  35,910 개
  • 현재 접속자 :  238 명