프로세스 구조
프로세스 구조는 4가지 영역으로 나뉜다.
- 스택 : 최상단 스택 주소를 가리키는 EBP, 함수 결과를 반환해줄 주소(return address), 함수와 관련된 인자나 변수를 저장하는 영역
- 힙 : 동적으로 할당된 메모리를 저장하는 영역. (ex. malloc) 이 영역의 메모리 주소를 통해 힙에 저장된 내용을 다른 영역에서 사용!
- 데이터 : 선언된 변수가 저장되는 영역(전역변수가 저장된다.)
- 코드 : 컴파일된 소스코드가 저장되는 영역
스택에 쓰이는 레지스터들 :program counter, stack pointer, EBP, EAX
program counter(pc)는 cpu 내부의 레지스터 중 하나로, 다음에 실행될 명령어의 주소를 가지고 있다.
stack pointer는 cpu 내부 레지스터 중 하나로, 스택에 데이터가 채워진 위치를 가르킨다.
EBP 얘도 레지스터인데, 우리가 함수를 작성할 때 함수 안에 다른 함수를 부를때마다 그 전에 stack pointer가 가르키던 주소를 스택에 집어넣고 EBP에도 저장한다.
이를 통해 프로그램 진행 중 문제가 생겼을 때, 어떤 함수에서 문제가 발생했는지 알 수 있게 된다.
EAX 얘도 레지스터인데, 스택에서 실행된 함수의 반환값을 저장하는 레지스터다!
데이터 영역은 두 가지로 나뉜다. (BSS, DATA)
BSS : 초기화되지 않은 전역변수.
DATA : 초기화된 전역변수
컨텍스트 스위칭
스케쥴러가 어떤 프로세스를 실행하다가, 이를 멈추고 다른 프로세스를 실행시키는 행위를 컨텍스트 스위칭이라 한다!
컨텍스트 스위칭은 빈번하게 일어나므로, 빠르게 실행하기 위해 어셈블리어로 작성되어 있는 경우가 많다.
이때 앞에 배웠던 program counter와 stack pointer이 저장하고 있는 두 주소값을
해당 프로세스의 PCB(Process Control Block. 프로세스의 상태를 저장하는 구조체)라는 곳에 저장해 놓고!
다른 프로세스로 넘어가서 작업을 시작하고 이 프로세스의 PCB에도 해당 값을 저장하고,
이제 처음에 했던 프로세스를 이어서 하기위해, PCB에 있던 데이터를 가져와 cpu의 pc와 sp를 업데이트하고 디스패치(ready->running)한다!
PCB에 저장되는 내용들
리눅스 PCB 예시
- Process ID
- Register value(PC, SP…)
- Scheduling info (Process state. running, block, ready…)
- Memory Info(memory size…)
프로세스간 커뮤니케이션(IPC, Inter Process Communication)
프로세스들이 서로 마음대로 접근해서 바꾸면? 당연히 문제가 된다!
하지만 프로세스간 통신 해야 될 경우도 분명히 존재한다.
- 성능을 높이기 위해 여러 프로세스를 만들어서 동시 실행
- 이 때 프로세스간 상태 확인 및 데이터 송수신 필요.
=> 그래서 프로세스간 통신이 필요하다.
프로세스간 공유하는 파일 사용하기
프로세스간 코드에 접근할 수는 없지만, 특정 저장매체를 공유할 수 있게 해서,
한 프로세스가 전달할 내용을 파일에 쓰고, 다른 프로세스가 해당 파일을 읽는 방식이다.
하지만 실시간으로 원하는 프로세스에 데이터 전달이 어려움…
이때, 프로세스들은, 다른 영역이 아닌 커널 공간(이 부분은 다른 프로세스도 비슷하므로)를 공유해 사용한다.
IPC는 쉽게 요약하면, 이 커널 공간을 통해 어떻게 공유할 지 결정하는 방법이라 할 수 있다.