커널에서는 하드웨어들을 관리하기 위해 하드웨어별 자료구조를 갖고 있어야 한다.
프로세스를 관리하기 위한 블럭(자료구조) 또한 가지고 있는데 이 블럭을 PCB(Process Control Block ) 라고 부른다.
또한 이러한 자료구조들은 metadata라는 하드웨어에 대한 정보를 가지고 있다.
PCB는 PID, PC ( Program Counter ), 레지스터 등의 정보를 갖고 있다.
( 📌 PC 는 다음 수행될 프로세스의 주소를 갖고 있는 곳 일종의 포인터라고 보면 될 것 같다. )
또한 PCB는 프로세스의 상태를 저장하게 되는데
프로세스가 CPU를 빼앗기고 I/O 와 같은 다른 작업을 기다리게 될때 수행되던 작업 내용을 PCB에 저장한다.
I/O 작업이 끝나고 CPU를 받기위한 대기 큐로 돌아오게 되면 PCB에서 작업 내용을 다시 불러온다.
이렇듯 PCB 는 프로세스의 기본정보와 수행 환경을 위한 정보를 갖는다.
Process가 CPU와 I/O 작업을 위해 기다리고 수행되는 과정은 아래 이미지와 같다.
운영체제가 실행되면 메모리에 Kernel이 가장 먼저 올라오고 그 다음 Shell이 올라온다.
그리고 다음 수행될 프로세스들이 올라오게 되는데,
이때 올라오는 프로세스들을 Child Process로 Shell이라는 Parent's Process를 복사함으로써 만들어 준다.
(꼭 Shell이 아니더라도 Parent Process는 될 수 있다.)
또한 프로세스마다 User stack, kernel stack 이 있는데
User stack 은 컴파일러가 만들어주고 프로그램 내부에서 함수를 실행할 때 사용하는 영역이다.
Kernel Stack 은 Kernel 영역 안에서 프로그램의 함수를 실행하기 위해 사용하는 영역이다.
fork()
exec()
커널 안의 System Call 함수를 설명하면
fork() : Child를 복사하는 SystemCall
exec() : 복사된 Child에 새로운 이미지(프로세스)를 덮어씌우는 SystemCall
wait() : Child 작업이 끝날때까지 CPU를 반납하고 정지되는 SystemCall
exit() : 작업의 종료와 함께 CPU를 반납, Parent에게 작업 종료를 알리는 SystemCall
main()
{
int pid;
pid = fork();
if (pid == 0) /* This is child */
{
execlp("/bin/ls", ...);
}
else /* This is parent */
{
wait();
}
이때 Parent와 Child 간의 CPU를 교환하는 과정을 Context Switch 라고 하는데 이 부분에 대해서는 다음 글에서 설명할 예정이다.
고건 교수님 강의
https://olc.kr/course/course_online_view.jsp?id=35&cid=51