프로세스란 메모리에 적재되어 CPU에서 실행중에 있는 프로그램을 의미한다.
메모리에 올라와 실행되고 있는 프로그램의 인스턴스이며 운영체제로부터 시스템 자원을 할당받는 작업의 단위이다.
스케줄링의 대상이 되는 작업(task)과 같은 의미로 쓰인다.
프로세스 내부에는 최소 하나의 스레드를 가지고있는데, 실제로는 스레드 단위로 스케줄링을 한다.
하드디스크에 있는 프로그램을 실행하면, 실행을 위해서 메모리 할당이 이루어지고,
할당된 메모리 공간으로 바이너리 코드가 올라가게 된다. 이 순간부터 프로세스라 불린다.
프로세스와 프로그램의 차이
프로그램 자체는 생명이 없다.
프로그램은 보조 기억장치(하드디스크, SSD)에 존재하며 실행되기를 기다리는 명령어(코드)와 정적인 데이터의 묶음이다.
프로그램의 명령어와 정적 데이터가 자원을 할당받고 메모리에 적재되면 생명이 있는 프로세스가 된다.
Text(Code) 영역 : 프로그램을 실행시키는 실행 파일 내의 명령어들이 올라간다.
Data 영역 : 초기화된 전역변수, static 변수의 할당을 위한 메모리 영역
BSS 영역 : 초기화되지 않은 전역변수, static 변수
Heap 영역 : 동적할당을 위한 메모리 영역
Stack 영역 : 함수 호출시 전달되는 인자(파라미터), 함수 내부에서 사용되는 지역변수, 복귀 주소(return address)를 위한 메모리 영역, 함수 호출이 완료되면 메모리가 해제된다.
스택 영역과 힙 영역 사이의 빈 공간은 왜?
컴파일 타임에 지역변수를 얼마나 사용할 지 미리 계산할 수 없기 때문에 런타임에 지역변수 선언 순서에 따라 스택영역은 위쪽으로 주소값을 매기고 동적 할당될 때 힙영역은 아래쪽으로 주소값을 매긴다. 스택 포인터와 힙 포인터가 만나면 메모리가 소진되었다는 의미다.
프로세스끼리 접근할 수 있을까?
프로세스는 별도의 주소 공간에서 실행되며, 한 프로세스는 다른 프로세스의 자원 영역에 접근할 수 없다. 만약 한 프로세스가 다른 프로세스의 자원에 접근하려면 프로세스 간의 통신(IPC)를 사용해야한다.
CPU는 하나인데 동시에 실행되어야 할 프로세스가 어떻게 여러개가 될 수 있을까?
CPU가 고속으로 여러 프로세스를 일정한 기준으로 순서를 정해서 실행한다.
CPU 할당 순서 및 방법을 결정하는 일 (어떤 프로세스를 running 상태로 보낼까?)
일정한 기준 : scheduling algorithm 을 통해서
대부분의 OS에서는 우선순위 알고리즘과 라운드 로빈 알고리즘을 혼합해 스케줄링 한다.
프로세스는 실행중에 프로세스 생성 시스템 호출을 이용해 새로운 프로세스를 생성할 수 있다. 이 때 프로세스 생성 순서를 저장하고 부모-자식 관계를 유지하여 계층적으로 생성한다.
운영체제나 응용 프로그램에서 요청을 받아 프로세스를 생성하면, 운영체제는 해당 프로세스에서 PCB를 만들어 주소 공간을 할당한다.
프로세스가 작업을 수행하려면 프로세서 점유 시간, 메모리, 파일, 입출력장치 등 자원이 필요하다. 자식 프로세스는 운영체제에서 직접 필요한 자원을 얻거나 부모 프로세스의 자원을 일부 사용할 수 있다. 이 때 부모 프로세스는 자식 프로세스가 사용하는 자원을 제한해서 특정 프로세스가 자식 프로세스를 너무 많이 생성하여 시스템에 부담을 주는 것을 막을 수 있다.
프로세스가 마지막 명령을 실행하면 종료하여 운영체제에 프로세스의 삭제를 요청한다. 또한 부모 프로세스는 자식 프로세스가 할당된 자원을 초과하여 자원을 사용할 때나 자식 프로세스에 할당한 작업이 더는 없을 때 자식 프로세스를 종료한다.
프로세스 제거는 프로세스를 파괴하는 것이다. 프로세스를 제거하면 사용하던 자원을 시스템에 돌려주고, 해당 프로세스는 시스템 리스트나 테이블에서 사라져 PCB를 회수한 후 디스크에 저장한다.
프로세스의 준비, 실행, 블록 상태만 이용하면 입출력 동작이 일반 연산보다 느려 시스템이 대부분 유휴상태이다.
다중 프로그래밍 환경에서도 프로세서의 동작시간이 입출력보다 짧아 프로세스 컨텍스트 스위칭이 일어난 후에도 기다리게 되므로 대부분 유휴시간이 된다.
시스템의 유휴시간 문제는 프로세스 중단(일시중단) 상태를 이용하여 해결할 수 있다.
운영체제는 새로운 프로세스를 생성하여 실행하거나 실행 중인 프로세스를 중단했다가 다시 실행하여 사용할 수 있다. 후자의 방법을 이용하면 시스템 전체의 부하를 증가시키지 않으면서 프로세스에 서비스를 제공할 수 있다.
중단 상태를 추가하면 실행에서 대기가 아닌 중단 상태로 전환하여 특정 이벤트의 발생을 기다리면서 블락 상태가 된다.
그리고 해당 이벤트가 발생할 때 준비상태로 가서 실행을 기다리는 것이 아닌 즉시 실행 상태로 바꿀 수 있는 이점이 있다.
프로세스를 중단한 원인을 제거하여 다시 실행하는 것을 재시작이라고 한다.
프로세스 중단과 재시작은 시스템 부하를 조절하는 데 상당히 중요하고, 다음 상황에서 주로 발생한다.
시스템에 장애가 발생하면 실행 중인 프로세스는 잠시 중단했다가 시스템이 기능을 회복할 때 다시 재시작할 수 있다.
프로세스에 의심스러운 부분이 있으면 실행 중인 프로세스를 중단하여 확인한 후 재시작하거나 종료할 수 있다.
처리할 작업이 너무 많아 시스템에 부담이 되면 프로세스 몇 개를 중단했다가 시스템이 정상 상태로 다시 돌아왔을 때 재시작할 수 있다.
대다수 시스템은 프로세스를 실행하기 전에 자원을 할당받고 실행을 시작하지만, 다중 프로그래밍 환경에서는 자원의 이용률과 시스템 효율을 높이려고 자원을 동적으로 할당한다. 이때 자원을 할당받으려고 기다리는 상태가 “블락"이고, 할당받은 자원을 기다리는 상태가 “중단"이다.
중단된 상태는 프로세스가 보조 메모리에 있고 이벤트를 대기 중인 상태이다. 중단 상태는 프로세스가 보조 메모리에 있지만 즉시 메인 메모리로 적재하여 실행할 수 있는 상태이다.
프로세스가 최초로 생성되는 상태, 운영체제에 프로세스의 PCB가 생성되면서 프로세스가 메인 메모리에 적재되어 실행 준비를 마친 상태이다.
프로세스가 기억장치를 비롯한 모든 필요한 자원들을 할당받은 상태에서 CPU를 할당받기 위해 기다리고 있는 상태이다. Ready Queue에 들어와있는 상태라고 얘기한다.
다시 말해, 어느 프로세스가 준비상태에 있다함은 CPU가 주어질 경우 그 프로세스가 즉시 실행할 수 있음을 의미하는 것이다. Ready Queue는 여러개를 사용하기도 하며, 자신의 차례는 CPU 스케줄러가 관리한다.
Ready Queue에 있던 프로세스가 자신의 차례를 부여받아 실제로 수행되는 상태로, 프로세스의 프로그램 코드가 기억장치로부터 읽혀지면서 CPU에 의해 실행되고 있는 상태이다. 다시 말해, 실행 상태란 기억장치나 CPU를 포함해 프로세스가 원하는 모든 자원을 할당받고 있는 상태를 의미한다.
CPU 스케줄러가 Dispatch()를 수행하면 준비상태에서 실행상태로 바뀌는데, 이때 주어진 시간(CPU time quantum)은 모든 프로세스마다 동일한데 이 시간을 다할 때까지 작업이 끝나지 않는다면 Ready 상태로 돌아간다. 이를 timeout(cpu lock으로부터 인터럽트)을 실행하여 작업한다. 즉 다시 Ready Queue에 삽입되는 것이다.
프로세스가 실행 상태에서 입출력이 발생했을 때, CPU는 입출력 관리자에게 작업을 맡기고 프로세스를 대기 상태로 만든다.이는 CPU 효율을 높이기 위해서 다른 상태로 옮겨둔 것이다. block() 을 실행하여 수행한다. 대기 상태의 프로세스들은 보통 입출력 장치마다 각각의 큐에서 기다린다.
이후에, 입출력 관리자가 해당 I/O를 완료했다면 인터럽트가 발생해 대기 상태의 프로세스 중에서 해당 프로세스를 찾는데 wakeup() 을 실행해 찾고 다시 Ready Queue에 들어간다. 원래는 스냅샷을 보면 현재 Running 상태의 프로세스가 Ready Queue로 들어가고 방금 대기 상태의 프로세스를 실행 상태로 바꾸는 과정이 일어나야 하는데 복잡하기 때문에 위처럼 처리된다.
프로세스가 자신의 작업을 모두 마치고 운영체제가 PCB를 제거하고 메인 메모리에서 빠져나간 상태이다. exit()를 실행하여 처리한다. 만약 오류나 강제 종료(abort)를 한다면 디버깅을 위해 abort 이전의 메모리 상태를 저장장치로 옮기는데 이를 코어 덤프(core dump)라고 한다.
CTRL + Z를 누르면 프로그램이 종료되지 않고 잠시 실행을 멈춘 상태가 되는데, 이를 휴식 상태라고 한다.
다른 말로는 stop 되었다고 한다.
메인 메모리에 PCB도 그대로 있고 프로세스의 데이터도 유지되기 때문에 resume 명령어를 통해서 재시작할 수 있다.
메모리가 꽉 차서 프로세스를 메모리 밖으로 내보내거나, 프로그램 오류로 인해 실행을 미룰 때, 바이러스가 발견되었을 때, 입출력이 계속 지연될 때 등의 이유가 발생한다면 보류 상태로 들어가게 된다.
보류 상태에서 메모리 밖으로 쫓겨난 프로세스는 swap 영역에서 보관된다. 여기서 주목할 점은 보류대기상태에서 인터럽트가 발생하면 보류준비상태로 가서 resume 된 후에 Ready Queue에 들어간다는 점이다.
- 보류준비상태 (suspended ready)
Ready 상태에서 보류가 발생한 것으로, 프로세서만 없는 상태이다.- 보류대기상태 (suspended wait/block)
blocked 상태에서 보류가 발생한 것으로, 프로세서 외 다른 자원이 없는 상태이다.
운영체제는 프로세스들의 실행 사이에 프로세스를 교체하고 재시작할 때 오류가 발생하지 않도록 관리해야한다.
이를 위해 운영체제는 프로세스 상태를 준비(ready), 블록(blocked), 실행(running) 상태로 분류하고 프로세스들을 상태 전이(state transition)를 통해 체계적으로 관리한다.
사용자가 프로그램을 실행하면 프로세스가 생성되고 준비큐(Ready Queue)에 추가된다.
프로세스는 프로세서(CPU)가 사용가능한 상태가 되면 CPU를 할당받는다.
이 때, 준비 리스트에 있는 프로세스들을 운영체제가 프로세스 스케줄링 알고리즘에 의해 실행 상태로 가야할 프로세스를 CPU로 할당하게 된다. 이 과정을 디스패칭이라고 하고 디스패처가 이 일을 수행한다.
즉, 준비 상태에서 대기하고 있는 프로세스 중 우선순위가 가장 높은 프로세스를 선정해 프로세서를 할당받아 실행 상태로 전이되는 과정이다.
프로세스는 실행상태에서 CPU를 이용해 연산한 후 CPU를 자발적으로 반납하고 작업이 끝나지 않았으면 다시 준비상태에 들어간다. 운영체제는 다시 준비큐(Ready Queue)의 첫번째에 있는 프로세스를 실행상태로 바꾸고 이 과정을 반복한다.
즉, CPU의 저장된 할당 시간을 모두 사용한 프로세스는 다른 프로세스를 위해 다시 준비 상태로 되돌아가는 것이다.
운영체제는 프로세스가 CPU를 자발적으로 반납하지 않고 독점하는 경우를 방지하기 위해 하드웨어적으로 인터럽팅 클록을 주기적으로 발생시켜 프로세스가 특정 시간 간격동안만 실행할 수 있도록 한다.
인터럽팅 클록이 발생되면 강제로 실행중인 프로세스의 CPU 제어권을 운영체제에게 빼앗기고 프로세스는 준비상태로 상태 전이된다.
만약 프로세스를 다시 사용하기 전에 입출력이 완료대기를 기다려야하는 상황이라면 완료될 때까지 자신을 블록한다.
입출력이 완료되면 운영체제가 프로세스를 블록상태에서 준비상태로 다시 전이 시킨다.
다시 말해, 현재 running 상태에 있는 프로세스A에서 입출력(I/O) 이벤트가 발생했을 때 프로세스A가 block 상태로 가게되고, 입출력(I/O) 이벤트가 종료된 프로세스는 다시 Ready 상태로 오게된다.
즉, 실행중인 프로세스가 입출력 명령을 만나면 인터럽트가 발생하여 입출력 전용 프로세서에게 CPU를 양도하고 자신은 대기 상태로 전이되는 과정이다.
입출력 작업이 완료되어 프로세스가 블록 상태에서 준비상태로 전이되는 과정
spooling
입출력 장치의 공유 및 상대적으로 느린 입출력 장치의 처리 속도를 보완하고 다중 프로그래밍 시스템의 성능을 향상시키기 위해 입출력할 데이터를 직접 입출력장치에 보내지 않고 나중에 한꺼번에 입출력하기 위해 디스크에 저장하는 과정이다.
ready, blocked 상태에는 여러 프로세스가 존재할 수 있다.
하지만, 싱글코어 CPU에서, running 상태의 프로세스는 단 하나만 존재한다.
인터럽트나 시스템 호출 등으로 실행 중인 프로세스의 제어를 다른 프로세스에 넘겨 실행 상태가 되도록 하는 것을 프로세스 컨텍스트 스위칭이라고 한다. 프로세스 컨텍스트 스위칭이 일어나면 프로세서의 레지스터에 있는 내용을 나중에 사용할 수 있도록 저장한다.
ex) 프로세스A가 실행 상태에 있던 도중 프로세스 B에 제어권을 넘겨주는 컨텍스트 스위칭
컨텍스트 스위칭에선 오버헤드가 발생하는데, 이는 메모리 속도, 레지스터 수, 특수 명령어의 유무에 따라 다르다.
그리고 컨텍스트 스위칭은 프로세스가 “준비->실행" 상태로 바뀌거나 “실행->준비, 실행->대기" 상태로 바뀔 때 발생한다.
현재 실행중인 프로세스에서 컨텍스트 스위칭을 요청하면, 우선 사용자 모드에서 커널 모드로 프로세스 제어가 넘어가면서 프로세스를 종료한다. 그리고 다시 시작할 수 있도록 프로세스의 현재 상태를 PCB에 저장하고 다음에 실행할 프로세스를 선택한다. 새로 실행될 프로세스 정보를 PCB에서 얻어와 프로세서에 재저장하고는 사용자 모드로 돌아와서 새로운 프로세스를 실행한다.
이러한 컨텍스트 스위칭은 시간 비용이 들어가는 오버헤드이고, 이 오버헤드는 메모리 속도, 레지스터 수, 특수 명령어의 유무에 따라 시스템마다 다르다. 그래서 운영체제를 설계할 때, 최대한 불필요한 컨텍스트 스위칭을 줄이는 것을 목표로 정한다.
컨텍스트 스위칭은 레지스터 컨텍스트 교환, 작업(task) 컨텍스트 교환, 스레드 컨텍스트 교환, 프로세스 컨텍스트 교환이 가능하다.
프로세스에 대한 정보는 PCB 즉, 프로세스 제어 블록또는 프로세스 기술자(process descriptor)라고 부르는 자료구조에 저장된다. 이 자료구조는 크게 9가지의 정보를 담고 있다.
운영체제가 각 프로세스를 식별하기 위해 부여된 프로세스 식별번호(PID, Process IDentification)이다.
CPU는 프로세스를 빠르게 교체하면서 실행하기 때문에 실행중인 프로세스도 있고 대기중인 프로세스도 있다. 그런 프로세스의 상태를 저장한다. (생성, 준비, 실행, 대기, 중단)
CPU 가 다음으로 실행할 명령어를 가리키는 값이다. CPU는 기계어를 한 단위씩 읽어서 처리하는데 프로세스를 실행하기 위해 다음으로 실행할 기계어가 저장된 메모리 주소를 가리키는 값이다.
운영체제는 여러개의 프로세스를 동시에 실행하는데, 이러한 프로세스가 CPU에서 실행되는 순서를 결정하는 것을 스케줄링이라고 한다. 이 스케줄링에서 우선순위가 높으면 먼저 실행될 수 있는데 이를 스케줄링 우선순위라고 한다.
프로세스가 접근할 수 있는 자원을 결정하는 정보다. 프로세스마다 어디까지 접근할 수 있는지에 대한 권한 정보이다.
최초로 생성되는 init 프로세스를 제외하고 모든 프로세스는 부모 프로세스를 복제해서 생성되고 이 계층관계는 트리를 형성한다. 그래서 각 프로세스는 자식 프로세스와 부모 프로세스에 대한 정보를 가지고 있다.
프로세스는 실행중인 프로그램이므로, 프로그램에 대한 정보를 가지고 있어야 한다. 프로그램에 대한 정보는 프로세스가 메모리에 있는 자신만의 주소 공간에 저장되고, 이 공간에 대한 포인터 값(메모리 주소)이다.
프로그램에 자원이 할당되고 메모리에 적재되면 실행중인 프로그램 인스턴스 즉, 프로세스가 된다. 따라서 프로세스는 자신에게 할당된 자원들의 주소를 가지고 있다.
프로세스가 실행상태에서 마지막으로 실행한 프로세서의 레지스터 내용을 담고 있다.
CPU에 의해 실행되는 프로세스는 운영체제에 의해 계속 교체되는데 교체되었다가 다시 자신의 차례가 되어서 실행될 때 중단된 적 없고 마치 연속적으로 실행된 것처럼 하기 위해 이 레지스터 정보를 가지고 있다.
멀티 코어 프로세서는 여러 개의 작업을 보다 효율적으로 한 번에 처리하기 위해 2개 이상의 프로세서가 붙어있는 직접회로를 말한다. 즉, ‘회로'를 의미한다.
멀티 프로세싱은 여러 개의 프로세서들이 협력하여 작업을 처리하는 방식을 의미한다. 즉, ‘처리방식'을 의미한다.
그렇다고 해서 멀티 코어 프로세서의 처리방식이 멀티 프로세싱이고, 멀티 프로세싱의 회로가 멀티 코어 프로세서가 되는 것은 아니다. 왜냐하면 멀티 코어 프로세서(예. 듀얼코어)라고 해서 멀티 프로세싱 방식으로만 처리하는 건 아니기 때문이다.
아래 예는 멀티 코어 프로세서들을 의미하는데,
싱글코어 CPU 4개, 듀얼코어 CPU 2개, 쿼드코어 CPU 1개이다.
다음은 듀얼코어에서의 처리방식을 나타낸 것이다.
듀얼코어가 멀티 코어 프로세서에 해당되는데, 이런 멀티 코어 프로세서가 멀티 프로세싱 방식으로만 처리하지 않음을 나타낸다. 왼쪽은 멀티 코어 프로세서(듀얼코어 CPU 2개)가 멀티 프로세싱 방식으로 일을 수행하고, 오른쪽은 멀티 코어 프로세서(듀얼코어 CPU 2개)가 멀티 프로세싱 방식이 아닌 독립적인 방식으로 처리하는 경우를 나타낸다.
https://sweetday-alice.tistory.com/167
https://brunch.co.kr/@toughrogrammer/15