상세 컨텐츠

본문 제목

프로세스 -1 (프로세스란)

운영체제

by AyaanDev 2022. 12. 28. 15:06

본문

반응형

프로세스란?

프로세스란 실행 중인 프로그램을 말한다.

프로그램은 실행되기 전 까지는 그저 보조기억장치에 있는 데이터 덩어리에 불과하다.

보조저장장치에 저장된 프로그램이 메모리에 적재되고 실행되는 순간 이를 프로세스라고 지칭한다.

 

프로세스 확인하기

리눅스 터미널에서 ps를 입력하면 현재 실행 중인 프로세스목록을 확인할 수 있다.

 

프로세스 종류

프로세스는 foreground Process와 background Process로 구분된다.

foreground Process: 사용자가 보는 앞에서 실행되는 프로세스

background Process: 사용자가 보지 못하는 뒷단에서 실행되는 프로세스

background Process에는 사용자와 직접 상호작용 할 수 있는 프로세스도 있지만 사용자와 상호작용하지 않고 정해진 일만 수행하는 프로세스도 있다. 이를 Daemon이라 한다. 윈도우 운영체제에서는 Service라 부른다.

 

터미널에서 -x 옵션을 부여해서 입력하면 daemon프로세스까지 확인 가능하다.

일반적으로 터미널에서 명령어를 실행하면 명령어의 수행이 완료되기 전까지는 다른 명령어를 실행할 수 없다.

다만 명령어 뒤에 &를 붙이면 background process로 실행되므로 터미널과 계속 상호작용할 수 있다.

리눅스에서 프로세스를 관리하는 명령어는 다른 게시글에서 더 자세히 정리해보도록 하겠다.

 

프로세스 상태

프로세스 상태에는 new,ready,waiting,running,terminated 로 나뉜다. 운영체제에 따라서 더 세분화해서 구분하는 경우도 있다. process state diagram은 아래와 같다.

출처: Abraham Silberschatz의 Operating System Concept

new: 프로세스가 생성중이다.

ready: 프로세스가 실행될 준비가 완료되었다.

running: 실행 중인 프로세스

waiting: I/O 혹은 어떠한 event가 끝나기를 대기하고 있는 상태이다.

terminated : 프로세스가 종료되었다.

 

프로세스가 처음 생성되면 new상태로 들어간다. 

초기화가 끝나고 프로세스가 실행될 준비가 완료되면 ready상태에 들어간다.

하나의 처리기는 한순간에 하나의 프로세스만 실행할 수 있으므로 본인의 차례가 될 때까지 기다리고 있는 상태가 ready상태이다.

ready상태에서 running상태로 변경될 때 Dispatch 되었다라고 표현한다.

interrupt가 발생하여 running상태에서 ready상태로 변경되기도 하는데 이는 본인에게 할당되어있는 시간이 끝났거나 다른 이유로 interrupt가 발생하여 cpu를 다른 프로세스에게 빼앗기는 경우이다.

running상태에 있던 프로세스가 어떤 I/O작업 혹은 다른 event가 발생할 때까지 실행을 중단해야 하는 경우 waiting상태로 전환된다. 

기다리고 있던 I/O혹은 event가 발생하면 다시 ready상태로 돌아가 본인의 차례를 기다리게 된다.

 

프로세스의 메모리 영역

프로그램이 메모리영역에 적재될 때 그 영역은 크게 4가지 부분으로 구분된다. 이때 메모리는 메모리의 사용자 영역을 말한다.

Text: 실행되는 코드가 저장되는 영역이다.

Data: 초기값이 있는 전역변수가 저장되는 영역이다.

BSS : 초기값이 없는 전역변수가 저장되는 영역이다.

Heap: 동적으로 할당되는 데이터가 저장되는 영역이다. C언어의 malloc , Java의 new키워드로 할당된 메모리가 Heap에 저장된다.

Stack: Activation Record가 저장된다. 이는 호출된 함수와 관련된 데이터들이라 생각하면 된다. 함수의 매개변수, 지역변수, return address, return value 등이 여기에 포함된다.

Text, Data, Bss와 같은 영역은 프로세스가 처음 생성되고 그 크기가 변하지 않는다. 따라서 이 영역을 정적 할당 영역이라 부른다.

Heap영역과 Stack영역은 프로세스가 실행되면서 그 크기가 계속해서 변하게 된다. 따라서 이 영역을 동적 할당 영역이라 부른다. 

 

메모리 누수(memory leak)

Heap영역에 할당된 데이터는 사용이 완료되면 할당해제되어 빈 공간으로 돌아간다. 더 이상 필요없는데이터가 메모리 영역을 반환하지 않고 점유하고 있으면 이러한 상태를 메모리 누수라 부른다. C언어에서는 free를 통해 프로그래머가 직접 메모리를 반환해주어야 하는 반면에 Java와 같이 GC(Garbage Collector)가 있는 언어의 경우 GC가 더이상 참조되지 않을 변수를 자동으로 검사해 메모리를 반환해 준다.

 

프로세스 제어블록(PCB)

CPU가 프로세스를 실행하기 위해 필요한 메타데이터가 담겨있는 구조체를 PCB라 부른다.

메모리는 커널 영역과 사용자 영역으로 나뉜다. 프로그램이 실행되어 프로세스가 되면 코드와 실행 중인 데이터들은 사용자 영역에 프로세스를 관리하기 위한 PCB는 커널영역에 저장된다.

 

PCB는 프로세스 생성 시에 만들어지고 실행이 끝나면 폐기된다. PCB에 담기는 주요 정보들은 아래와 같다.

1. 프로세스 ID(PID)

프로세스에 부여되는 고유한 번호이다. 같은 프로그램을 여러 번 실행하더라도 각각의 프로세스는 서로 다른 pid를 가지게 된다. 운영체제에 따라 PPID(부모 프로세스의 PID) 또한 저장되는 경우도 있다.

리눅스에서 ps명령어를 입력하면 PID를 확인할 수 있다. ps -f 를 입력하면 ppid까지 확인가능하다.

2. 프로세스 상태

현재 프로세스가 어떤 상태인지도 PCB에 기록된다. 이는 앞서 언급한 것처럼 new, running, waiting, ready, terminated로 구분된다. 운영체제에 따라 상태 구분을 더 세밀하게 하는 경우도 있다.

 

3. 레지스터 값

프로세스가 실행되면서 적재된 cpu register의 값들이 저장되어 있다. 이는 프로세스가 다시 실행될 때 복구되어 이전까지의 연산을 이어서 그대로 실행할 수 있도록 해준다.

PC(Program Counter Register) 또한 PCB에 저장되어 있다. PC는 다음에 실행할 명령어가 어디인지를 저장하고 있어 cpu가 실행해야 할 명령어가 무엇인지를 알  수 있게 해 준다.

 

4. CPU 스케쥴링 정보

프로세스 우선순위, 스케줄 큐에 대한 포인터와 스케줄 매개변수들을 포함한다.

 

5. 메모리 관리 정보

프로세스마다 메모리에 저장된 위치가 다르다. PCB에는 프로세스가 어느 주소에 저장되어 있는지에 대한 정보가 담겨있다. PCB에는 Base Register, Limit Register, page table 또는 segment table과 같은 정보가 저장된다.

 

6. 회계 정보

CPU 사용시간과 경과된 실제 시간, 시간제한과 같은 정보들이 저장된다. PID를 따로 분류하긴 했으나 회계정보에 포함되는 정보이다.

 

7. 사용한 파일과 입출력 장치 목록

프로세스에 할당된 입출력 장치와 열린 파일에 대한 정보가 저장된다.

 

문맥 교환(Context Switch)

하나의 프로세스에서 다른 프로세스로 실행 순서가 넘어갈 때 문맥교환이 발생한다. 프로세스 A가 실행되다가 프로세스 B로 CPU가 넘어간다고 가정해 보자.

직전까지 실행되던 프로세스 A는 프로그램 카운터를 비롯한 각종 레지스터 값, 메모리 정보, 실행을 위해 열었던 파일이나 사용한 입출력 장치 등 지금까지의 중간정보를 백업해야 한다. 그래야 다시 CPU를 할당받았을 때 실행을 이어갈 수 있기 때문이다. 이러한 중간정보를 문맥이라 한다.

이후 실행될 프로세스 B는 저장되어있던 문맥을 PCB에서 참조하여 다시 CPU에 채우고 실행이 지속된다.

프로세스 계층 구조

프로세스는 실행 도중 시스템 호출을 통해 다른 프로세스를 생성할 수 있다. 다르게 말하면 프로세스는 다른 프로세스에 의해서만 생성될 수 있다. 이 때문에 프로세스는 계층구조를 띄게 되는데 많은 운영체제는 계층구조를 통해 이러한 프로세스를 관리한다.

리눅스 터미널에서 pstree를 입력하면 이러한 계층구조를 눈으로 확인할 수 있다.

 

최초의 프로세스는 리눅스에서는 systemd, 유닉스에서는 init, macOS에서는 launchd라고 한다.

최초의 프로세스의 PID는 항상 1이며 모든 프로세스의 최상단에 있는 부모 프로세스이다.

최초의 process인 systemd의 pid가 1인것을 확인할 수 있다.

 

반응형

관련글 더보기

댓글 영역