CPU가 미리 자료를 ‘예측’ 한다는 것은, 시키지 않은 일을 한다는 것이다. 하지만 CPU가 예측해서 발생한 ‘심각한’ 보안 문제가 있는데, 그걸 CPU 게이트 문제라고 부른다.
특정 저장소에 접근 요청을 하면, 접근 권한이 없다고 반환이 되는데, 문제는 해당 저장소에 접근하고 읽은 다음에 접근권한이 없다고 반환한다는 것이다. 읽은 데이터는 CPU의 케싱이 되어있다. 이를 특정 연산을 통해 원하는 값을 간접적으로 취할 수 있다.
비정상적인 연산으로 케싱내용을 탈취할 수 있다. 악성 유저가 무작위로 RAM을 읽는 행위를 한다면, 다른 유저의 작업 정보를 케싱해뒀던 영역을 악성유저의 케싱 영역과 겹쳐지는 기적(?)이 일어날 수 있어서, 필요한 정보를 해킹을 할 수 있다.
간단한 예시로 AWS를 쓰고있다면, 악성 유저는 같은 하드에 등록되어있는 다른 유저의 인증서 정보를 CPU게이트 원리를 이용해 탈취할 수 있다는 것이다.
컴퓨터의 자원은 CPU,RAM,HDD을 통해 사용하는 경우가 많다. RAM+HDD는 Virtual Memory 형식으로 적용한다. 윈도우 기준으로는 자원을 스레드에게 준다. (곰 책에선 프로세스에게 나눠준다고 설명된다)
가상메모리는 프로세스에 전달되고, 이를 관리하기 위해서 OS에서 PCB라는 개념이 있다.
CPU를 주로쓰는건 스레드고 버추얼 메모리를 사용하는 건 프로세스라고 생각하면 좋다.
CPU는 연산의 주체이다. 컴퓨터에 실행되는 프로세스는 몇천개 이상은 된다. 하지만 CPU의 코어 갯수는 한정적이기 때문에 병목현상이 일어나기 일수다. 그래서 비동기적으로 처리를 하는게 기본이다. 프로세스의 요청을 모두 처리하기위해 CPU 코어에 시분할사용을 적용한다.
PCB는 프로세스 컨트롤 블록의 약자다. 이름에서도 알 수 있듯이 프로세스를 제어하기 위한 모든 정보가 다 들어있다. 이는 리액트의 파이버가 비슷한 구조를 띄고 있다는 것을 알 수 있다. 리액트 훅 파이버 내부를 까보면 next라는 속성이 있는데, 이는 다음 훅을 호출 하기위해 연결점을 제공하며, 전체적으로 훅들은 Linked List 구조를 띄고있다.
PID(process id값) 보통 32bit 양의 정수로 들어가있다.
Stack: 정적 영역(static) R -> 문자열 “hello” / RW(읽기 쓰기) -> 전역변수
Heap -> 동적 데이터 malloc 으로 주소를 할당받을 수 있다.
Code (text section 기계어) -> 실행중인 코드의 주소도 PCB에 들어간다.
프로그램이 메모리에 올라와 프로세스가 되는 과정:
프로그램이 HDD에 저장되어 있다면(설치됨), 이를 RAM 메모리에 올리고 Instance화를 한다. 운영체제가 프로그램을 읽어서, 메모리에 적재를 하고 PCB생성을 한다. 가상메모리도 할당을 한 다음 하나씩 정보를 떼와서 연산을 시작한다. 이때 프로그램이라고 부르지 않고 프로세스라고 부른다. 프로세스는 프로그램의 실행 형태라고 생각하면 된다.
대기상태가 추가되면서 프로세스의 상태관리가 매우 복잡해진다. 입출력 요청을 때렸을 때 Response를 받을 때 까지 대기를 한다면, 블록킹 I/O다. 비동기 요청은 요청자의 상태가 매우 중요하다. 요청자가 요청을 하고 대기상태로 빠진다면 블록킹, 반대 상황이라면 논 블록킹 요청이다.
운영체제가 프로세스를 관리할때 상태를 관리한다고 하는데, 디스패치라는 개념이 많이 등장 할 예정이다. 디스패치의 주체는 OS이고, 디스패치의 대상을 선정하는 행위를 디스패치라고 한다.
대기 큐에서 프로세스 상태가 Ready일때 운영체제에서 dispatch를 하는데, 이때 코어가 8개면 8개를 꺼내서 dispatch를 해준다. dispatch가 끝나면 자원할당 과정이 시작된다.
리액트에서도 마찬가지로 스케줄러에서 파이버들 중 리렌더에 해당되는 컴포넌트 / 훅 들을 탐색하는 작업을 갖는다. 리액트의 dispatch 동작 구조는 운영체제의 프로세스 관리 운용 방식과 매우 흡사하다는 것을 다시한번 체감했다.
Process의 상태에는 Sleep과 Suspend라는 중요한 상태가 더 있다.
suspend 상태는 외부요인으로 인해 의도치 않게 띈 상태다. sleep은 자발적으로 전환된 상태다. Ready된 스레드들을 모아둔 Queue에서 각자 스레드에서 sleep / suspend 로 인해 큐에서 잠깐 빠지게 된다. 상태가 전이된 스레드는 대기열에서 이탈하게 되는데, sleep으로 1ms 대기열에서 이탈한다면, 1ms이 지나고 이탈 상태에서 대기열로 재진입을 시도한다. 재진입을 하는 과정에서 추가된 시간을 소모하기에 1ms보다 더 많은 시간을 쉬게된다.
suspend도 sleep과 마찬가지로 이탈한 다음 재진입하는 추가적인 시간이 걸린다.
CPU의 코어는 한정적이기에, 한번에 모든 일을 처리하기 위해서 비동기적으로 context를 진행한다. 이러한 흐름을 제어하는 행위를 문맥교환(context switch)이라고 부른다.
CPU가 연산을 하는 과정엔 프로세스의 상태변화가 일어나는데, 상태는 Register에 담겨진다.
상태가 장시간 변동되지 않는 프로세스는 운영체제에서 swap처리를 한다. RAM->HDD로 옮기거나, 연산을 하지 않을 문제가 있는 프로세스같은 경우엔 dump처리를 하는 경우도있는데, 이럴 때 suspend 상태로 전이될 수 있다.