운영체제의 기본이 되는 프로세스에 대해 복습한다.
간단하게, 실행중인 프로그램을 의미한다. HDD, SSD 등의 저장 장치에 저장되어있던 프로그램이라는 데이터 묶음을 실행하기 위해 메모리에 로드하는 순간, 그 프로그램은 프로세스가 된다.
프로세스는 Process address space라는 구조대로 메모리에 적재된다. 그 형태는 다음 그림과 같다.
만약 특정 프로세스에서 무한정으로 재귀함수가 실행되면, 호출된 함수에 대해 메모리를 할당하는 stack 영역이 계속 커져 heap 영역을 침범하게 된다. 이를 방지하기 위해 일정 수준 이상으로 재귀 함수가 호출되면 프로세스는 강제 종료된다.
CPU는 한번에 하나의 작업만 수행할 수 있다는 말을 들은적이 있을 것이다. 그런데, 실제로 우리는 컴퓨터에서 수많은 프로그램을 동시에 실행하고 사용한다. 어떻게 된 일일까? 이는 context switching에 의해 가능한것이며, 이 context switching은 process state에 기인한다. 지금부터 이를 알아본다.
위의 그림에서 볼 수 있다시피, 프로세스는 다음과 같은 상태를 지닌다.
앞서 컴퓨터가 어떻게 여러개의 프로그램을 동시에 실행하는지 물었던 것을 기억하는가? 그 비밀이 바로 context switching에 있다.
위에서 살펴본 process 상태 중에 ready, running, waiting을 주목하라. 실제 컴퓨터에서는 이 상태들에 해당하는 프로세스들을 번갈아가면서 지속적으로 실행한다. 그리고 프로세스를 변경해주는 주기를 사람이 눈치채기 힘들정도의 짧은 시간으로 설정하여 빠르게 실행중인 프로세스를 전환한다. 이를 바로 Context switching이라 한다.
이러한 Context switching을 하려면, 현재 실행중인 프로세스의 정보를 저장하는 것이 필요하다. 바로 이 때 사용하는 자료구조가 PCB (프로세스 제어블럭)이다. PCB에는 현재 CPU에 의해 실행중인 프로세스에 관하여 CPU 레지스터가 갖고 있는 정보들을 저장한다. 이렇게 PCB에 프로세스 정보를 저장해두고, 다른 프로세스의 PCB에 있는 정보를 CPU의 레지스터에 로드하여 다른 프로세스를 실행하게 된다. 그리고 각 프로세스의 정보들은 운영체제에서 관리하는 priority queue에 저장되어있는데, 이는 프로세스 상태에 따라서 ready queue와 각 waiting 상태를 담당하는 각 i/o 디바이스 대응 queue에 저장되어 있다.
이렇게 context switching이 일어나는 조건에는 대표적으로 다음의 두가지가 있다.
이렇게 특정 프로세스들이 중단되고, ready queue에 들어가 있을 경우 CPU는 어떤 프로세스를 레지스터로 로드하여 실행시킬지 결정해야 하는데, 이를 위해 프로세스 스케쥴링 알고리즘들이 존재한다.
앞서서 프로세스의 정보와 상태, 그리고 context switching에 대해 설명했다. 그리고 이러한 설명을 통해, 프로세스들은 각자 독자적인 정보를 갖고 있다는 것을 언급했다. 그런데 만약, 프로세스간 공유해야하는 정보가 있을시에는 어떻게 해야하는가? 각자의 독립적인 공간이 존재한다면, 그 독립적인 공간에는 서로가 접근할 수 없는것은 아닌가?
이러한 궁금증을 해결해주는 것이 바로 IPC(Interprocess communication)이다. 이러한 IPC에는 크게 다음과 같은 두가지 방식이 있다.
말 그대로 프로세스 A와 B가 있을 때, A가 B에게 message를 전달하고 B는 그 message를 수신하는 방식으로 프로세스간 통신이 이루어진다. 이 때 프로세스 A가 메시지를 발신하기 전에는 프로세스 B가 실행될 수 없고, 이에 따라 waiting 상태에 빠지게 된다. 그리고 프로세스 A가 message 전송이 완료되었을 때 프로세스 B가 그 정보를 통해 다시 실행된다. Message passing 방식에서는 이러한 프로세스 동기화 과정을 커널에 위임하여 자동으로 처리하게 한다. 그림을 보면 해당 message가 상대 프로세스의 메모리로 직접 전달되는 것이 아닌, 커널을 거쳐서 전달되는것을 알 수 있다. 단, 커널에 모든 작업이 위임되므로 OS가 감당하는 오버헤드가 커진다.
프로세스 A의 정보를 프로세스 B로 전달한다는 큰 틀은 같으나, 그 방식이 다르다. 앞선 Message passing은 커널에 의해 직접적으로 상대 프로세스에게 정보가 전달됐다. 하지만 Shared memory는 이름에서 알 수 있듯이 프로세스간 공유할 수 있는 메모리 영역을 지정하고, producer process가 생산한 정보를 shared memory에 던져놓는다. 그후에 consumer process는 shared memory에 있는 정보를 가져다가 읽는 형태로 간접 전달된다.
이 때, consumer가 원하는 data가 아직 shared memory에 writing되었는지 알 수가 없기 때문에, 이러한 프로세스 동기화 과정을 직접 정의해주어야 한다. 따라서, 커널에 의해 IPC가 일어나는것이 아니기 때문에 overhead는 적지만 운용의 난이도가 올라간다.
이제부턴 실제 면접에서 대답할 수 있을만한 짤막한 요약으로 마무리를 해보려 한다.
프로세스란?
context switching
IPC