프로그램(Program)
특정 작업을 위한 명령문의 집합
정적인 파일로 기기 내 저장공간에 저장되어있지만 메모리에 올라가있지 않은 실행 가능한 파일
프로세서(Processor)
CPU, 그래픽 프로세서(graphic processor), 입출력 프로세서(I/O processor)와 같은 하드웨어 처리기
프로세스를 처리하는 주체
프로세스(Process)
- 메모리에 올라와 실행 중인 프로그램 인스턴스
- 스케줄링의 대상이 되는 작업(task)과 유사
- 컴퓨터에서 연속적으로 실행되고 사용자 공간에 형성되는 컴퓨터 프로그램
- 프로세스는 서로 독립적인 메모리 공간을 가지므로, 다른 프로세스의 영역이나 자료구조에 바로 접근할 수 없음
- 프로세스가 다른 프로세스의 자원에 접근하려면 프로세스 간의 통신(IPC) 사용
- 프로그램이 실행 -> 메모리에 올라가고 운영체제로부터 시스템 자원 할당 받음, 프로세스 인스턴스 생성
- 인스턴스가 생성 -> 프로그램 실행에 필요한 내용이 컴퓨터 메모리(ram)에 적재
- 운영체제는 프로세스마다 고유한 번호(프로세스 ID)를 할당
- 프로세스에 관한 정보는 운영체제 커널에 의해 관리
- 프로세스를 만들고, 실행하고, 대기시키고, 종료시키는 모든 관리는 커널에 의해 수행
프로세스 간의 통신(IPC) : 프로세스들 사이에 서로 데이터를 주고받는 행위 또는 그에 대한 방법이나 경로. 파일, 파이프, 신호, 소켓, 메세지큐 등
프로그램과 프로세스의 비교
프로그램
- 어떠한 작업을 위해 실행할 수 있는 파일
- 보조 기억장치(하드디스크, SSD)에 존재하며 실행되기를 기다리는 명령어(코드)와 정적인 데이터의 묶음
- ex) 내 pc에 깔려있는 크롬,줌,한글 등 파일
프로세스
- 내 pc에 깔려있는 프로그램을 더블 클릭해서 실행하게 되면 CPU를 차지하면서 수행하는 수행 주체
- 즉, 프로그램 한 개의 인스턴스가 프로세스
- 프로그램은 하나지만 이 프로그램을 실행하는 프로세스는 여러개일 수 있음
- ex) 크롬을 더블클릭해서 실행으로 뜨는 여러개의 크롬창 중 크롬 실행파일 자체는 프로그램, 그 실행파일을 클릭해서 만든 여러 개의 창은 프로그램을 실행하는 인스턴스, 프로세스
프로세스의 특징
프로그램의 다중 인스턴스
하나의 프로그램을 여러번 실행시키면, 실행될 때마다 독립된 프로세스가 생성
프로세스가 접근 할 수 있는 메모리 공간
- 독립된 메모리 영역(Code, Data, Stack, Heap 의 구조)을 할당 받음
- 프로세스의 코드와 데이터 영역은 실행 파일에 결정된 상태로 적재-> 실행 중 크기가 변하지 않음
- 프로세스는 사용자 공간의 최대 범위까지 동적 할당 받으면서 힙 영역과 스택 영역을 늘려갈 수 있음
- 시스템 전체에는 하나의 커널 주소 공간이 있음
- 모든 프로세스는 커널 주소 공간을 공유
코드(Code) 영역 (text 영역)
- 프로세스 코드(사용자가 작성한 코드, 라이브러리 함수 코드)가 적재되는 영역
- 실행 파일을 구성하는 명령어들이 올라가는 메모리 영역
- 함수, 제어문, 상수 등이 여기에 지정
- 컴파일 타임에 결정되고 중간에 코드를 바꿀 수 없게 Read-Only 로 지정
데이터(Data) 영역
- 프로세스의 전역 변수들과 정적 변수들이 적재되는 영역
- 프로그램이 구동되는 동안 항상 접근 가능한 변수가 저장
- 전역변수, static 값을 참조한 코드는 컴파일 하고 나면 Data 영역의 주소값을 가르키도록 변화
- 프로그램의 시작과 함께 할당, 프로그램이 종료되면 소멸
- 실행 중도에 전역변수가 변경 될 수도 있으니 이 영역은 Read-Write로 지정
힙(Heap) 영역
- 프로세스가 실행 중에 동적 할당받는 영역
- 런타임에 크기가 결정되는 메모리 영역
- 사용자에 의해 메모리 공간이 동적으로 할당되고 해제
- 참조형의 데이터의 값이 저장 ex) 클래스, 클로저
- Heap은 메모리의 낮은 주소에서 높은 주소의 방향으로 할당
스택(Stack) 영역
- 함수가 호출될 때, 지역변수, 매개변수, 함수로부터 돌아갈 주소 등이 저장되는 영역
- 지역 변수와 같은 호출한 함수가 종료되면 되돌아올 임시적인 자료를 저장하는 독립적 공간
- Stack은 함수의 호출과 함께 할당되고 완료되면 소멸
- 컴파일 타임에 크기가 결정되기 때문에 무한히 할당 할 수 없음
- 재귀함수가 너무 깊게 호출되거나 함수가 지역변수를 너무 많이 가지고 있어 stack 영역을 초과 시 stack overflow 에러
스택영역과 힙영역 사이에 빈 공간
- 컴파일 타임에 지역변수를 얼마나 사용할지 미리 계산할 수 없음
- 런타임에 지역변수 선언 순서에 따라 스택영역은 위쪽으로 주소 값을 매기고 동적 할당될때 힙영역은 아래쪽으로 주소값을 매김
프로세스 주소 공간
- 프로세스가 실행 중에 접근할 수 있도록 허용된 주소의 최대 범위(사실상 CPU주소 공간)
- 사용자 공간 + 커널 공간(프로세스가 실행 중에 시스템 호출을 통해 커널에 진입하여 커널 함수를 실행하기 때문)
- 최대한 데이터를 공유하여 메모리 사용량을 줄이기 위해 프로세스 공간 분리
사용자 공간
프로세스의 코드, 데이터, 힙, 스택 영역이 순서대로 할당되는 공간.
힙은 데이터 영역 바로 다음부터 시작하고, 스택은 사용자 공간의 바닥에서 시작하여 거꾸로 자람.
힙 영역은 높은 번지로 자라고, 스택은 낮은 번지로 자람.
커널 공간
프로세스가 시스템 호출을 통해 이용하는 커널 공간.
커널 코드를 실행하는 것은 사용자 프로세스
커널 코드, 커널 데이터, 커널 스택 존재
프로세스의 주소 공간은 가상 공간
- 운영체제는 각 프로세스마다 프로세스의 가상 주소 공간과 물리 메모리의 물리 주소 공간을 연결하는 매핑 테이블을 두고 관리
- 가상 주소 데이터는 메모리에 분산되어 있는데, 운영체제는 물리 메모리의 비어 있는 공간에 나누어 적재하고 매핑 테이블에 기록
프로세스 사이 가상 주소 공간은 충돌하지 않음
- 프로세스는 자신의 매핑 테이블을 통해 물리 메모리에 접근
- 각 프로세스 영역은 운영체제에 의해 물리 메모리의 서로 다른 공간에 배치됨
프로세스의 관리
- 프로세스에 대한 정보는 프로세스 제어블록(PCB) 또는 프로세스 기술자라고 부르는 자료구조에 저장
- 운영체제 커널은 시스템 전체에 하나의 프로세스 테이블을 두고 모든 프로세스의 정보를 관리
- 프로세스를 생성할 때마다 프로세스 제어 블록(PCB)을 생성하여 프로세스의 정보를 저장하고, 테이블의 비어 있는 항목에 프로세스 번호(PID)와 함께 PCB를 연결
프로세스 테이블
프로세스 제어 블록
프로세스당 하나씩 존재하고, 프로세스가 생성될 때 만들어지고 종료되면 삭제
프로세스 번호(PID)
프로세스를 식별하는 고유 번호
운영체제가 각 프로세스를 식별하기 위해 부여된 프로세스 식별번호
부모 프로세스 번호(PPID)
프로세스는 프로세스에 의해 생성되며 이들 사이에는 부모-자식 관계가 형성
최상위 프로세스를 제외하고 모든 프로세스는 부모 프로세스를 가지며, PCB에는 부모 프로세스 ID가 저장
최초로 생성되는 init 프로세스를 제외하고 모든 프로세스는 부모 프로세스를 복제해서 생성
계층관계는 트리를 형성 -> 각 프로세스는 자식 프로세스와 부모프로세스에 대한 정보를 가지고 있음
프로세스 상태 정보(Process State)
생성 초기 상태, 실행되고 있는 상태, 준비 상태, 블록 상태
커널은 프로세스의 상태를 바꿀 때마다 PCB에 상태 정보를 저장
프로세스 컨텍스트 정보
커널은 프로세스 컨텍스트(PC,SP,범용 레지스터 등)를 PCB에 저장
스케줄링 정보
스케쥴링 : 운영체제가 여러 개의 프로세스가 CPU에서 실행되는 순서를 결정
스케줄링에서 우선순위가 높으면 먼저 실행될 수 있음
PCB에는 커널이 스케줄링 시 참고하는 우선순위, 프로세스가 사용한 CPU시간, 할당받아 실행한 시간 등이 저장됨
종료 코드
프로세스가 종료할 때 종료 이유를 부모 프로세스에게 전달하기 위한 정수 값으로 종료한 프로세스의 PCB에 저장
종료코드는 eixt 시스템 호출의 매개변수 값이나 main()함수의 리턴 값
좀비 프로세스 : 종료되었는데 부모가 종료코드를 읽어가지 않은 상태의 프로세스
프로세스의 오픈 파일 테이블
실행 중에 열어놓은 파일에 관한 정보들
회계 정보
CPU사용 총 시간, 실행을 시작하여 경과한 총 시간 등을 통해 컴퓨터 사용료를 계산하거나 성능 통계를 낼 때 사용
프로세스의 소유자 정보
권한
프로세스가 접근할 수 있는 자원을 결정하는 정보
프로그램 카운터
CPU가 다음으로 실행할 명령어를 가리키는 값
프로세스를 실행하기 위해 다음으로 실행할 기계어가 저장된 메모리 주소를 가리키는 값
프로세스의 데이터와 명령어가 있는 메모리 위치를 가리키는 포인터
프로그램에 대한 정보는 프로세스가 메모리에 가지는 자신만의 주소 공간에 저장
프로세스에 할당된 자원들을 가리키는 포인터
실행문맥
프로세스가 실행상태에서 마지막으로 실행한 프로세서의 레지스터 내용
CPU에 의해 실행되는 프로세스는 운영체제에 의해 계속 교체되며 교체후 연속적으로 실행하기 위해
프로세스의 생명 주기와 상태 변이
- 어느 시점에서 실행되고 있는 프로세스는 단 한개이며, 여러 개의 프로세스를 번갈아 가며 실행
- 프로세스 생명주기(상태 전의) : New - Ready - Running - Waiting - Terminated
- 시공유 시스템에서는 Running 상태에서 할당된 시간이 종료(Expired)되면, Waiting 상태를 거치지 않고 바로 Ready 상태로도 변할 수 있음
New 상태
- 프로세스가 이제 막 메인메모리에 올라온 상태. 실행 불가능
- 커널은 새 프로세스의 코드와 데이터를 메모리에 적재하고 PCB를 만들어 프로세스 테이블의 빈 항목에 등록되며 프로세스 상태를 New로 기록
- CPU를 점유하고 있는 상태가 아니라, CPU를 점유하길 희망하는 상태
- 준비 상태에서 실행 상태로 넘어가려면 작업 스케줄러가 선택
Ready 상태
- 변수 초기화 등 기초 준비작업을 모두 끝나고 실행을 할 수 있는 상태
Running 상태
- CPU가 실제로 프로세스를 수행하고 있는 상태
- 프로세스의 PCB에 상태를 Running으로 기록하고 CPU에게 프로세스를 실행
- 시간 할당량(time slice)이 지나면 다시 Ready상태로 변화
Wait 상태
- 프로세스 도중에 I/O 작업이 필요하여 I/O 작업을 수행하는 상태
- CPU는 I/O를 기다리며, 다른 프로세스를 수행
- Waiting 상태가 끝나면 프로세스는 다시 Ready 상태가 되고, 잠시 후 다시 Running 상태
( Blocked 상태 )
- 자원을 요청하거나 입출력을 요청하고 완료를 기다리는 상태
- 프로세스가 실행 상태에서 시스템 호출을 일으켰을 경우 커널은 현재 프로세스를 Blocked 또는 Wait 상태로 만들고, 스케줄링을 통해 Ready 상태의 프로세스를 선택하여 현재 프로세스와 컨텍스트를 스위칭
Terminated/Zombie 상태
- 프로세스가 종료하면 커널은 프로세스가 차지하던 메모리와 할당받은 자원들을 모두 반환하고 닫음
- 프로세스는 종료할 때 종료코드를 남기는데 PCB에 저장된 채 남음
Terminated/Out 상태
- 최종적으로 프로세스가 종료된 상태
- 사용하던 메모리 영역이 해제
- 부모 상태가 좀비 상태의 자식 프로세스의 PCB에서 종료코드를 읽어갈 때 커널은 좀비 상태의 PCB를 시스템에서 제거하고, 좀비 프로세스는 시스템에서 완전히 사라짐
디스패치(Dispatch)
디스패치란 준비 상태에서 실행 상태로 전이되는 과정
작업 스케줄러가 해당 프로세스를 선택하여 실행되어지는 것으로, 이때 실행된 프로세스가 CPU를 점유
인터럽트(Interrupt)
인터럽트 신호를 받게되면, 실행중이던 프로세스는 준비 상태로 전이
우선순위(Priority)가 높은 프로세스를 실행 상태로 전이
프로세스는 각각 우선순위를 부여받고, 우선순위에 따라 프로세스가 준비 상태로 전이되거나, 실행 상태로 전이
입출력 혹은 이벤트 대기(I/O or event wait)
CPU를 점유하고 있는 프로세스가 입출력 처리를 해야만 하는 상황이라면, 실행되고 있는 프로세스는 실행 상태에서 대기/보류 상태로 변화
대기 상태로 바뀐 프로세스는 입출력 처리가 모두 끝날때까지 대기 상태
실행 상태이던 프로세스가 대기 상태로 전이됨과 함께, 준비 상태이던 또다른 프로세스가 실행 상태로 전이
대기 상태인 프로세스는 우선순위가 부여되지 않으며 스케줄러에 의해 선택될 수 없음
입출력 혹은 이벤트 완료(I/O or event completion)
입출력 처리가 끝난 프로세스는 대기 상태에서 준비 상태로 전이되어 스케줄러에게 선택될 수 있음
추가로 프로세스를 종료(Terminate)시킬 때에도 Blocked 상태를 거칠 수 있음
프로세스 스케줄링
- 시스템의 자원을 효율적으로 사용하기 위해 어느 프로세스가 CPU를 차지할 것인가에 대한 순서 또는 방법을 결정짓는 작업
- CPU 스케줄러는 이러한 프로세스가 생성된 후, 관리의 범주를 나누어 종료될 때까지 모든 상태 변화를 조정
고수준 스케줄링 (장기 스케쥴링, 작업 스케쥴링, 승인 스케쥴링)
- 가장 큰 틀에서 이루어지는 CPU 스케줄링
- 시스템 내의 전체 작업 수를 조절하여 어떤 작업을 시스템이 받아들일지 또는 거부할지, 동시에 실행 가능한 프로세스의 총 개수 결정
- 작업 요청이 오면 스케줄러가 시스템의 상황을 고려하여 작업을 승인할지, 거부할지 결정
중간수준 스케줄링
- 중지와 활성화로 전체 시스템의 활성화된 프로세스 수를 조절하여 과부하 방지
- 일부 프로세스를 중지 상태로 옮김으로써 나머지 프로세스가 원만하게 작동하도록 지원
- 프로세스의 상태 중 보류 상태에 해당, 저수준 스케줄링이 원만하게 이루어지도록 완충하는 역할
- 보류된 프로세스는 처리 능력에 여유가 생기면 다시 활성화
저수준 스케줄링 (단기 스케쥴링)
- 실제로 작업이 이루어지는 스케줄링
- 어떤 프로세스에 CPU를 할당할지, 어떤 프로세스를 대기 상태로 보낼지 등을 결정
- 준비 상태에 있는 프로세스 중 하나를 골라 실행 상태로, 실행 상태에 있는 프로세스를 대기 상태로, 대기 상태의 프로세스를 준비 상태로 보냄
스케줄링의 목적
- 공평성: 모든 프로세스가 자원을 공평하게 배정, 자원 배정 과정에서 특정 프로세스가 베제 불가능
- 효율성: 시스템 자원이 유휴 시간 없이 사용되도록 스케줄링, 유휴 자원을 사용하려는 프로세스에는 우선권
- 안정성: 우선순위를 사용하여 중요 프로세스가 먼저 작동하도록 배정, 시스템 자원을 점유하거나 파괴하려는 프로세스로부터 자원을 보호
- 확장성: 프로세스가 증가해도 시스템이 안정적으로 작동하도록 조치, 시스템 자원이 늘어나는 경우 이 혜택이 시스템에 반영
- 반응 시간 보장: 응답이 없는 경우, 사용자는 시스템이 멈춘 것으로 가정하기 때문에 시스템은 적절한 시간 안에 프로세스의 요구에 반응해야함
- 무한 연기 방지: 특정 프로세스의 작업 무한 연기 불가능
스케쥴링 할당 방식
선점형 스케줄링
- 어떤 프로세스가 CPU를 할당받아 실행 중이더라도 운영체제가 CPU를 강제로 빼앗을 수 있는 방식
- 문맥 교환과 같은 부가적인 작업으로 인해 낭비가 생김
- 하나의 프로세스가 CPU를 독점할 수 없기 때문에 빠른 응답시간을 요구하는 대화형 시스템이나 시분할 시스템에 적합
- ex) 인터럽트 처리 : CPU가 인터럽트를 받으면 현재 실행 중인 작업을 중단하고 커널을 깨워서 인터럽트를 처리시키며, 인터럽트 처리가 완료되면 기존 작업으로 돌아감
비선점형 스케줄링
- 어떤 프로세스가 CPU를 점유하면 다른 프로세스가 이를 빼앗을 수 없는 방식
- 선점형 스케줄링보다 작업량이 적고 문맥 교환에 의한 낭비도 적음
- CPU 사용 시간이 긴 프로세스 때문에 CPU 사용 시간이 짧은 여러 프로세스가 오랫동안 기다리게 되어 전체 시스템의 처리율이 떨어짐
- 과거의 일괄 작업 시스템에서 사용하던 방식
구분 | 선점형 | 비선점형 |
작업 방식 | 실행 상태에 있는 작업을 중단, 새로운 작업 가능 | 실행 상태에 있는 작업이 완료될 때까지 다른 작업이 불가능 |
장점 | 프로세스가 CPU를 독점할 수 없기에 대화형이나 시분할 시스템에 적합 | CPU 스케줄러의 작업량이 적고, 문맥 교환에 의한 낭비가 적음 |
단점 | 문맥 교환의 오버헤드가 많음 | 기다리는 프로세스가 많아 처리율이 떨어짐 |
사용 | 시분할 방식 스케줄러 | 일괄 작업 방식 스케줄러 |
중요도 | 높음 | 낮음 |
프로세스 우선순위
- 대부분의 CPU 스케줄러는 우선순위를 사용
- 일반 프로세스 중에서도 우선순위가 서로 다르며 사용자가 조절할 수 있음
CPU 집중 프로세스와 입출력 집중 프로세스
- 프로세스는 생성된 후, 준비, 실행, 대기 상태를 거쳐 완료
- 준비 상태는 CPU를 할당받기 위해 기다리는 상태이므로 실제 작업이 일어나는 것은 실행 상태와 대기 상태
- CPU 버스트 : CPU를 할당받아 실행하는 작업
- 입출력 버스트 : 입출력 작업
CPU 집중 프로세스
대부분의 시간을 계산 중심의 일을 하느라 보내는 프로세스, CPU 속도가 성능 좌우
수학 연산과 같이 CPU를 많이 사용하는 프로세스, 즉 CPU 버스트가 많은 프로세스
I/O 집중 프로세스
입출력 작업을 하느라 대부분의 시간을 보내는 프로세스, 입출력 장치나 시스템의 속도가 성능 좌우
저장 장치에서 데이터를 복사하는 일처럼 입출력을 많이 사용하는 프로세스
- 입출력 집중 프로세스가 실행상태로 가면 입출력 요구에 의해 대기 상태로 옮겨지기 때문에 다른 프로세스가 CPU를 사용 가능
- 사이클 훔치기 : 입출력 집중 프로세스가 실행 상태에 먼저 들어가는 경우
- 두 프로세스가 같이 있을 때는 입출력 집중 프로세스를 먼저 실행 상태로 옮기는 것이 효율적
- 입출력 집중 프로세스가 실행 상태로 가면 입출력 요구에 의해 대기 상태로 옮겨지기 때문에 다른 프로세스가 CPU를 사용할 수 있음
- CPU 집중 프로세스가 먼저 실행 상태로 가게되면 타임아웃이 날 때까지 다른 프로세스가 실행 불가능
전면 프로세스와 후면 프로세스
포그라운드 프로세스 (전면 프로세스, 상호 작용 프로세스)
터미널 사용자로부터 입출력을 독점하는 프로세스
사용자에게 키보드로 입력을 받는 워드 프로세서
GUI를 사용하는 운영체제에서 화면의 맨 앞에 놓인 프로세스
운영체제는 터미널에서의 사용자 입력을 모두 포그라운드 프로세스로 보냄
백그라운드 프로세스 (후면 프로세스, 일괄 작업 프로세스)
사용자와의 대화를 필요하지 않는 프로세스
사용자의 입력 없이 작동
압축이 끝날 때까지 사용자의 입력이 필요없는 압축 프로그램
프로세스의 계층 구조
부모 자식 프로세스의 실행
fork() - 자식 프로세스를 생성하는 시스템 호출 함수
exit() - 현재 프로세스의 종료를 처리하는 시스템 호출 함수
wait() - 부모가 자식 프로세스가 종료할 때 까지 커널 내에서 대기하는 시스템 호출 함수
부모가 자식을 생성한 후 자식의 종료를 기다리는 경우
자식이 부모보다 먼저 종료한 경우
좀비 프로세스
종료 후 방치된 자식 프로세스
- 자식프로세스가 exit()시스템 호출을 실행하면 exit()는 부모 프로세스에게 자식의 종료를 알리는 SIGCHLD신호를 전달
- 부모가 이 신호를 받았을 때 wait()시스템 호출을 부르도록 작성되어 있지 않다면 죽은 자식 프로세스는 계속 좀비 상태로 남음
- wait()를 실행하지 않는다면 자식 프로세스는 종료하였지만 좀비 상태로 PCB와 프로세스 테이블에 항목이 남아있어 살아있는 것 처럼 보여져, 쉘에 ps명령을 입력하면 좀비 프로세스도 프로세스 리스트에 나타남
좀비 프로세스 제거
부모 프로세스의 SIGCHILD 신호 핸들러가 wait()를 호출
부모 프로세스를 강제 종료하여 좀비는 init프로세스의 부모가 되고, init프로세스는 주기적으로 wait() 시스템을 호출
고아 프로세스와 입양
부모가 먼저 종료한 자식 프로세스
프로세스 오버레이
- 현재 실행 중인 프로세스의 주소 공간에 새로운 응용 프로그램을 적재하여 실행
- 프로세스가 execlp(), execv(), execvp() 등으로 시스템 호출을 하면 exec()는 호출한 프로세스의 주소 공간에 새로운 응용프로그램의 코드,데이터,힙,스택을 올리게 되어, 호출 프로세스의 모든 영역들이 사라짐
https://blog.hexabrain.net/256
https://frtt0608.tistory.com/146
https://bowbowbow.tistory.com/16
https://velog.io/@jhon3242/Process-%EB%9E%80-%EB%AC%B4%EC%97%87%EC%9D%B8%EA%B0%80