https://cocoon1787.tistory.com/848
작업 단위
프로그램은 파일이 저장장치에 저장되어 있지만 메모리에는 올라가 있지 않은 정적인 상태 > 이러한 프로그램을 실행 > 운영체제로부터 CPU를 할당받고 실행되고 있는 상태가 프로세스이다.
즉 프로세스는 실행 중인 프로그램
프로그램이 실행 중이다 == 디스크에 저장되어 있던 프로그램을 메모리에 저장한 뒤 운영체제의 CPU 제어권을 받을 수 있는 상태가 된 것이다.
옛날에는 노트북이나 pc에 cpu가 한 개뿐 > cpu가 부족하다.
오늘날은 두 개의 cpu를 가졌다 수십 개의 프로그램 실행이 가능하다
이런 일이 가능한 것은 cpu를 가상화했기 때문이다.
물리적으로는 cpu가 1,2개이지만 마치 무한대로 공급되는 것처럼 착각하게 함
물리적으로 모자라는 cpu를 어떻게 가상화할 것인가?
결국 분할 타임 셰어링, 번갈아가면 쓴다.
cpu를 여러 개의 프로그램이 번갈아가면서 사용하는 원리를 통해 cpu를 가상화함
이제 cpu를 가상화해서 여러 개의 프로그램이 동시에 실행되는 효과를 얻었다.
이제 그 때 실행되는 상태를 추상화한 것이 프로세스이다.
여기에는 또 주소 공간이라는 개념 필요
메모리도 모자라는데 이것을 여러 개의 실행 중인 프로그램이 사용하려면
이것도 가상화 필요
주소 공간을 통해 물리적 공간이 아니라
가상화된 버트 메모리같은 것을 각 프로세스별로 보유
> 프로세스는 마치 프로그램 입장에서 보면 컴퓨터라는 기계를 cpu도 자기가 독점하고 메모리도 자기가 독점한다고 착각함
> 게다가 메모리는 자기가 원하는 만큼 무한 대로 존재한다고 착각함
> 이것이 이제 프로세스
이렇게 생성된 프로세스에 관련해서 이 프로세스 관련된 api라는 것이 존재,
이것이 운영 체제가 제공하는 기능함수이다.
물리적 공간과 추상화된 공간의 차이
시스템 콜을 제공해야 함.
그래서 프로세스를 처음에 만들 때 관여하는 프로세스를 만들거나, 만든 거를 파괴하거나, 프로세스 사이에 특정 프로세스가 다른 프로세스의 결과를 기다리게 하거나 등
프로세스를 제어할 수 있는 방법 필요
프로세스가 잠시 멈추게 했다가 이어 실행하게 하거나, 프로세스를 중단시키거나 등
그런 것과 관련된 시스템 콜들을 운영체제에서 코너를 통해서 제공
또 프로세스의 상태 파악도 가능
이 시스템에서 실행 중인 프로세스가 뭐뭐 있는지를 알아내는 시스템 콜 등
여러 시스템 콜이 있다. 시스템 콜로 프로세스 관리 가능
실행파일별로 PID 존재, 프로세스 별로 식별 가능한 ID Number,
실행 파일을 두 개 실행하면 프로세스 2개 존재, PID 두 개 존재
그림 참고(2 intro)
1. 프로그램 실행하면 하드에서 메인메모리로 로딩 과정 필수
2. 커널은 시스템콜을 처리하거나 장치의 효율적 공유 등 작업함
3. 커널을 위해 정의된 코드도 메인메모리 탑재 필수임. 이 과정은 부팅이라고 한다. 로딩은 프로그램 실행파일을 메인메모리로 탑재하는 것, 커널 위한 코드가 메인 메모리로 탑재하는 것은 부팅
4. 여기서는 프로그램을 2개 실행해서 로딩이 2개, 물리적 구조상의 메모리에서 두 개의 프로세스가 있다.
5. 그림 위는 추상화된 메모리를 나타냄 실제 물리적 메모리 xxx
6. 프로세스별로 pid 존재
7. 추상화된 메모리 공간에서는 둘 다 같은 20만 번지이지만 실제 물리적 메모리 공간에서는 40만, 50만 처러 다른 곳에 위치함. 주소변환 과정을 통해 가상화된 메모리에서는 같은 주소인 것처럼 보인다.
8. 프로세스에서 running 상태이다가 IO요청(prinf 대표적)을 만나면 해당 프로세스는 blocked 상태가 되고 다른 프로세스 ready 상태였던 게 running 상태가 된다.
9. 그리고 running 중인 프로세스에서도 IO요청을 만나면 둘 다 blocked 상태가 됨
10. 먼저 IO 요청이 끝난 프로세스가 다시 running 상태가 됨
11. 이처럼 프로세스는 running, ready, blocked 상태가 프로세스별로 상태가 존재하며 요청에 따라 상태 전환이 이뤄짐
물리적 메모리와 추상화된 메모리의 차이 (상태 전환과 IO 요청 등에 따른)
프로그램 실행하면 메인메모리 탑재(Loading)는 필수다.
그림 참고(4 process)
1. 프로세스 간 상태 전환(context switching)이 이뤄지면 1이 레디가 되면 2는 running, 반대는 반대처럼 이뤄짐
2. 이 때 상태 전환할 때 그 단면(레지스터들 pc, sp 등)이 보존되어야 함
3. 이후 다시 running 될 때 단면을 복원함
4. 이 때 쓰는게 Process Control Block임. PCB
상태 전환할 때 단면을 보존하고 복원하는 과정이 필요하다.
context switching > PCB
Trap > 커널스택
5 Process API 교안 참고
https://www.youtube.com/watch?v=TMy8RJx1Yk0&list=PLGgVuvaPty_3iqdv4-iME_bfDA-MwTUAy
direct = cpu가 직접 처리함, 성능업
그러나 분할 타임 셰어링 등 cpu를 운영체제가 컨트롤하다 보면 cpu를 직접 사용할 수 없음
cpu를 직접 사용하는 것이 성능이 좋음, 그렇다면 운영체제의 컨트롤을 유지하면서 성능을 업하게 하는 방법? > 제한적 직접 실행 메카니즘
cpu의 두 가지 모드
커널모드(privileged 모드, 특권 모드)
cpu가 할 수 있는 모든 일
인터럽트 관련 처리, IO 관련 일 등 커널 모드에서만 가능
CPU가 어떤 일을 할 수 있다 없다는 주로 특정 명령어가 보여서 실행할 수 있다 없다고 구분
유저 모드일 때는 시스템 전반적인 IO 관련된 거나 인터럽트 관련된 명렁어 자체가 아예 없는 것처럼 보임
특권을 갖는 명령어들을 커널 모드에서 명렁어의 풀 셋이 다 보임
시스템 콜
트랩
CPU는 물리적으로 하나이지만 모드가 있어 두 가지로 작동을 한다 기억하기
유저 프로그램이 사용하는 user space
code, data, stack/heap 등
//re
cpu를 가상화할 때 필요한 메카니즘
제한적인, 직접적인?
직접적인 == 성능의 손실을 없게 하기 위해 cpu를 직접 사용한다
그러나 직접 사용할 경우
direct execution은 결국 프로그램 카운터pc가 다이렉트로 가리킨다는 뜻
트랩이 걸렸을때 유저모드에서 바로 커널모드로 가는 것(pc가 확 튄다)
유저모드와 커널모드
Exeception
Interrupt
System call
유저 공간과 커널 공간이 함께 쉽게 공유할 수 있는 곳이 레지스터이다.
그래서 레지스터 이용함
간단한 예시, 제한적직접적 메카니즘
5p
커널모드(OS)
1. 프로세스 리스트 시작점 생성
2. 프로그램 위한 메모리 할당, 프로그램이 메모리에 탑재(로딩)
3. 스택을 셋업, 커맨드 라인에 argv 입력한 것을 스택에 초기값으로 적절하게 넣음
4. 커널 스택 채우기 > 커널 스택에 레지스터 값들이나 pc값 채움
5. return-from-trap > 명령어를 cpu가 실행하면 아래가 한번에 실행
하드웨어(CPU)
1. 레지스터 복원(커널 스택에서) > 레지스터를 덮어쓴다(처음이지만 덮어씀!)
2. 유저모드로 이동, 메인으로 점프 > 1에서 복원하기 때문에 자동으로 점프
프로그램(유저모드)
1. 메인 실행
2. 시스템 콜 호출(write() 내부에 INT), trap into OS(OS가 커널모드)
하드웨어
1. 커널 스택에 레지스터 저장
2. 커널 모드로 이동, 트랩 핸들러로 점프 (약속된 장소로 점프!)
커널모드(OS)
1. 트랩 핸들, 처리(여기서는 write(), 출력 등 하겠죠) > 시스템콜 일함
2. return-from-trap
하드웨어(CPU)
1. 커널 스택에서 레지스터 복원
2. 유저모드로 이동, 트랩 이후 PC값으로 점프
프로그램(유저모드)
1. 작업끝. 메인에서 리턴
2. trap(via exit()) (메인의 return이나 exit())
커널모드
1. 프로세스 메모리 공간 정리, 프로세스 리스트 등록된거 제거
Q. 프로세스 사이에 스위치(context switch)가 일어났을 때 어떤 메카니즘으로 실행?
요약
유저 프로그램이 실행되다가 커널로 컨트롤이 넘어와야 커널이 cpu라는 제한된 자원을 나눠쓰도록 스케줄링을 해줌
1. 커널에서 cpu를 나눠쓰기 위한 스케줄링 함
커널에서 cpu를 나눠쓰기 위한 스케줄링 함
유저 프로그램이 협조적, cooperative한 경우
유저 프로그램이 정기적으로 시스템 콜을 사용하면서 (yield) 커널에 컨트롤 넘김.
그러나 희망적이지 않고 대부분 사용 안함
운영 체제가 모든 걸 컨트롤함(대부분)
타이머를 통해 cpu에 인터럽트 건다.
인터럽트라는 트랩이 걸리면서 트랩 핸들러로 진입
트랩 핸들러에서 인터럽트 관련 처리함
타이머가 건 인터럽트는 주어진 시간이 끝나면 다른 프로세스로 교체
== context switching, 문맥 바뀐다.
하드웨어에서 벌어지는 일들은 한번에 일어남.
OS(커널모드)
1. 트랩 테이블 초기화
하드웨어
1. 트랩 핸들러 주소 기억 "CPU는 주소를 알아야 함"
2. 타이머 핸들러
커널모드
1. 인터럽트 타이머 시작
하드웨어
1. 타이머 시작, 주기적으로 CPU에 인터럽트 검(X ms, 미닛세컨마다)
---
프로그램(유저모드)
1. 프로세스 A 시작
하드웨어
1. 타이머 인터럽트
2. 커널스택에 A 레지스터 저장
3. 커널모드로 이동, 트랩핸들러로 점프
커널모드
1. 트랩 핸들, 트랩 처리 = 여기서는 타이머라 스위치 호출
2. switch() 호출
PCB-context(A)에 A 레지스터 저장
PCB(B)의 레지스터 복원
커널스택 B로 스위치
3. return-from-trap(into B)
하드웨어
1. 커널스택B에서 레지스터 복원
2. 유저모드로 이동, B의 pc로 점프
프로그램
1. 프로세스 B 실행