NEW 기획 디자인 개발 프로덕트 아웃소싱 프리랜싱

개발

레스토랑에 비유해서 알아보는 운영체제

오늘은 간만에 좀 흥미로운 주제로 글을 써보고자 합니다. 바로 운영체제입니다. 그런데 이제 뜬금없이 레스토랑을 곁들인…

 

오늘 글로 이 주제를 선택한 이유는 지금 운영체제 수업을 듣고 있어서 그런 것도 있는데… 교수님께서 다소 복잡할 수 있는 개념들을 비유를 통해 설명해 주셨던 게 이해에 있어 큰 도움이 되었기 때문입니다.

 

그래서 저도 나름대로 시나리오까지 짜가면서(?) 운영체제의 특징, 프로세스와 쓰레드의 개념을 비유로 설명하고자 합니다. 다만 비유를 하다 보니 일부 생략하거나 부정확한 비유가 있을 수 있다는 점 양해 바랍니다. 각 섹션 아래에 정석적인 설명을 적어놓았으니, 심화 개념은 직접 찾아보시기를 권장합니다.

 

이번 글을 통해 운영체제와 프로세스, 쓰레드에 대한 기본 개념을 정리하고 싶으신 분들께 도움이 되기를 바랍니다.

 

 

읽기 전에

이번 글에서 다루고자 하는 내용은 다음과 같습니다.

  • 운영체제의 특징
  • CPU와 RAM
  • 프로세스의 등장 배경
  • 프로세스의 특징
  • 쓰레드의 등장 배경
  • 쓰레드의 특징

 

 

OS 레스토랑에 오신 것을 환영합니다

OS 운영체제
©thenounproject

 

안녕하세요 여러분, 햄버거 전문점 OS 레스토랑 이 이번에 새롭게 문을 열었다고 해서 찾아가 봤습니다. 마침 보이는 가게 슬로건은… “고객님이 원하시는 햄버거를 대신 만들어드립니다”라고 하네요[1].

 

아, 레스토랑 지배인이 등장했습니다. 지배인 이름은 커널(Kernel)이라고 합니다[2].

 

사실 커널은 이 동네에서 소문난 악덕업주(?)입니다. 고용한 요리사들이 잠시라도 쉬는 걸 엄청 싫어한다고 합니다[3]. 깔끔은 또 얼마나 떠는지, OS 레스토랑 내에서는 매 요리를 만들 때마다 작업대를 따로 만들라고 요리사에게 강요합니다[4]. 요리사 입장에서는 악덕업주처럼 느껴지겠만, 그만큼 위생에 신경을 쓴 것이니 고객 입장에서는 안심이네요.

 

OS 레스토랑 은 식당인 만큼 우리가 익숙하게 알고 있는 몇 가지 규칙들이 적용되어 있는데, 한 번 살펴봅시다.

 

OS 운영체제
©thenounproject

 

우선 홀과 주방이 철저하게 분리되어 있다고 합니다[5]. 사실 예전에 음식에 불만을 가진 한 고객이 있었는데, 주방에 들어와 난동을 피우고 떠나버렸다고 합니다. 그 때문에 다른 고객에게 제공할 요리까지 망치고 말았죠. 커널은 그날 이후로부터 홀과 주방을 철저하게 분리해서 고객들이 함부로 주방에 들어오지 못하게 했다고 합니다.

 

두 번째로 이 식당에서 요리를 먹으려면 지배인을 통해 주문을 해야 합니다[6]. 레스토랑에서 제공하는 메뉴도 있지만, 원하는 레시피가 별도로 있다면 미리 전달해달라고 이야기하네요. 그러면 레시피대로 조리한 음식을 제공해 줄 수 있다고 합니다[7]. 이처럼 커널은 고객에게는 한없이 친절하기 때문에, 고객이 말을 더듬거려도 인내심을 갖고 기다려줍니다[8]. 고객이 오랜 시간 동안 고민을 한다던가, 심지어 말을 하지 않고 계속 가만히 있어도요.

 

아무튼 지배인이 고객으로부터 주문을 받으면, 주문을 주방으로 넘깁니다. 그러면 요리사가 들어온 주문대로 조리를 한 후, 만들어진 음식이 제공됩니다. 덕분에 고객은 주문만 잘 넣으면, 주방의 구조를 정확히 모르더라도 요리사가 만들어준 맛있는 음식을 어디서든 동일한 맛으로 맛볼 수 있죠[9].

 

사실 커널은 레시피 관리, 재료 관리, 레스토랑 운영 등 대부분의 일을 혼자 할 만큼 유능합니다. 하지만 요리만큼은 그의 전문 분야가 아니었기에, 마침 이번에 유능한 요리사 한 명을 고용했다고 합니다. 그의 얼굴이나 한 번 보도록 하죠.

 

이번 섹션에서 비유한 내용을 정석적인 설명으로 나타내면 다음과 같습니다.

  1. 운영체제(Operating System)는 사용자(User)와 하드웨어 사이에서 동작하는 시스템 소프트웨어다.
  2. 커널(Kernel)은 운영체제 내에서 동작하는 시스템 소프트웨어로, 메모리 관리 및 디스크 관리, 프로세스 관리 등 하드웨어와 가까운 서비스를 제공한다.
  3. 커널의 대표적인 역할 중 하나가 바로 CPU 사용량을 극대화하는 것이다.
  4. 운영체제는 프로세스가 다른 프로세스의 메모리 영역을 침범하지 못하도록 내부 보안(Protection) 기능을 제공한다.
  5. 하드웨어 제어권은 전적으로 운영체제가 관리하며, 사용자가 애플리케이션 단계에서 직접 접근할 수 없게 만든다.
  6. 운영체제는 사용자와 상호작용할 수 있는 인터페이스(UI)를 제공한다.
  7. 프로그램(Program)은 실행 가능한 형태의 바이너리 코드를 말한다. 일반적으로 HDD, SSD 같은 저장 장치에 저장되어 있다.
  8. 운영체제는 입출력(I/O) 장치 관리 기능을 제공한다.
  9. 운영체제는 하드웨어 제조사마다 상이한 기능을 추상화하여 제공함으로써, 하드웨어 종류에 종속받지 않고 동일한 프로그램을 수행할 수 있게 해준다. 대신 하드웨어 제어권과 프로그램 제어권은 전적으로 운영체제가 관리한다.

 

 

CPU - 저희 식당 대표 요리사입니다

CPU
©thenounproject

 

새로 온 요리사의 이름은 CPU라고 합니다[1]. 실력이 아주 뛰어난데, 무엇보다 음식을 만드는 속도가 정확하면서 빠르다고 합니다.

 

하지만 CPU는 성격이 워낙 수동적이라고 합니다. 시키는 일은 잘 하지만, 뭔가 알아서 일을 하지는 않는 타입입니다. 커널은 눈치껏 하지 않고 시키는 것만 하는 CPU가 못마땅하지만, 그래도 시키는 일만큼은 잘 해내니… 일단 뽑아놓고 직접 일을 시키기로 했습니다.

 

CPU
©thenounproject

 

커널은 CPU에게 식당의 주방 구조를 소개해 주려고 합니다. 커널은 앞서 말했듯이 조금 특이한 방식으로 주방을 운영하고 있는데, 각 요리를 만들 때마다 작업대를 따로 세팅하는 것입니다[2].

 

커널은 워낙 깔끔한 성격이라, CPU가 이리저리 주방을 돌아다니면서 어지럽히는 걸 원하지 않습니다. 그래서 커널은 주문을 받으면 CPU에게 각 요리 별로 작업대를 새로 만들어 넘겨줄 테니, CPU에게는 그 작업대에서 바로 조리를 시작하라는 이야기를 들었습니다[3].

 

CPU는 커널의 말이 잘 이해가 되질 않아 좀 더 자세히 설명을 해달라고 부탁했습니다.

 

이번 섹션에서 비유한 내용을 설명으로 나타내면 다음과 같습니다.

  1. CPU(Central Processing Unit), 프로세서(Processor)는 컴퓨터에서 논리/산술 연산을 수행하고 입력받은 명령어를 실행시키는 하드웨어다.
  2. 프로세스(Process)는 프로그램이 실행되어 메인 메모리(RAM)에 올라가 있는 상태로, OS의 입장에서 관리하는 하나의 작업 단위다.
  3. CPU는 RAM에서 수행할 프로세스에서 필요한 정보를 레지스터로 가져온 후 작업을 수행한다.

 

 

프로세스 - 요리 별로 작업대가 있어야지

커널은 이것도 이해하지 못하냐며 한숨을 푹 쉬었습니다. 그리곤 마지막으로 설명해 줄 테니, 까먹지 말고 잘 들으라고 이야길 덧붙였죠.

프로세스
©thenounproject

 

커널은 CPU를 데리고 가서 작업대를 하나 보여줍니다. 작업대는 크게 4개 영역으로 구분되어 있었습니다[1]. 커널은 주문이 들어오면 요리 별로 이렇게 생긴 작업대를 마련해줄 것이라고 이야기했습니다.

 

작업대는 널찍한 사각형으로 생긴 것이 마치 도마 같았습니다. 조리할 레시피를 담아두는 공간[2], 여러 군데에서 쓸 기본 조미료들을 담아두는 공간[3], 현재까지 중간 조리한 재료를 보관해두는 공간이 있었습니다[4]. 요리 도중에 혹시 모르게 필요한 공간도 있을 수 있으니, 그 공간도 남겨두었군요[5].

 

프로세스
©thenounproject

 

커널은 요리 별로 작업대를 따로 설치하고 싶어 하는데, 강박증이 있는지 작업대를 처음 세팅하는 것에도 나름의 규칙이 있다고 합니다. 바로 새 작업대를 설치할 때에는 순서를 헷갈리지 않게 반드시 근처의 작업대를 현재 상태 그대로 복사하여 만드는 것입니다[6].

 

커널은 이런 식으로 작업대를 마련해준 후 레시피를 새 것으로 바꿔줄 테니, 그때부터 새 요리를 만들어달라고 CPU에게 부탁을 했습니다[7].

 

이번 섹션에서 비유한 내용을 설명으로 나타내면 다음과 같습니다.

  1. 프로세스는 자신이 점유한 메모리 영역을 역할에 따라 아래의 4가지로 구분한다.
  2. 텍스트(Text): 현재 프로세스에서 실행 중인 프로그램의 바이너리 코드를 저장
  3. 데이터(Data): 전역 변수, 상수 등을 저장
  4. 스택(Stack): 지역 함수, 변수처럼 현재 실행 중인 컨텍스트와 관련된 정보를 저장
  5. 힙(Heap): 런타임에 할당할 메모리 영역을 저장
  6. 리눅스를 기준으로, 모든 프로세스는 다른 프로세스로부터 파생된 트리 구조를 가진다(fork())
  7. 자식 프로세스는 부모 프로세스의 메모리를 완전 복사한 후, 자식 프로세스에서 새롭게 실행할 코드를 불러온다(exec())

 

 

멀티태스킹 - 여러 요리를 동시에 만들 순 없을까?

멀티태스킹
©thenounproject

 

이렇게 CPU는 커널로부터 작업대를 만드는 규칙을 들었습니다. 뭐, 자기는 커널이 가져다주는 작업대에서 시키는 일만 하면 되니 별 상관없는 이야기였지만요. 하지만 점심시간처럼 여러 주문이 한 번에 쏟아질 때에는 문제가 생겼습니다. 처음에는 들어온 순서대로 요리를 처리했는데, 이것이 문제가 생겼습니다. 일부 고객이 요리가 늦게 나오는 것에 대해 불쾌감을 표시했기 때문입니다.

 

심지어 어떤 고객은 패티를 무한 개 얹어달라는 레시피로 주문을 넣었는데, 이 주문을 CPU가 그대로 받아들이는 바람에 다음 요리를 만들지 못하는 경우도 생겼죠.

 

멀티태스킹
©thenounproject

 

커널은 고민에 빠졌습니다. 커널은 CPU에게 혹시 여러 주문을 동시에 처리해줄 수 있냐고 물어봤지만, CPU는 자기도 몸이 한 개인지라 어려울 것 같다고 난색을 표했습니다.

 

멀티태스킹
©thenounproject

 

그때, 커널은 좋은 생각이 났습니다. 한 요리를 하나씩 하지 않고 여러 요리를 조금씩 하다 보면, 여러 요리를 동시에 처리하는 것처럼 만들 수 있기 때문이었죠[1]. 그래서 커널은 주방에 작업대를 여러 개 설치할 수 있게 만들 테니 여러 주문이 동시에 들어오면 각 요리를 번갈아가면서 해달라고 부탁했습니다. 다행히 CPU는 그건 괜찮을 것 같다고 대답하는군요.

 

커널은 CPU를 위해 직접 작업대를 교체해주기로 했습니다[2]. 하지만 얼마나 자주 작업대를 교체해주어야 하는지를 결정하지 못해 고민에 빠졌습니다. 작업대를 교체하는 것은 좋은데, 이것도 커널이 해주는 일이라 시간이 걸렸기 때문이죠[3]. 커널은 일단 적당한 시간이 지날 때마다 작업대를 교체해주기로 합니다[4].

 

이번 섹션에서 비유한 내용을 설명으로 나타내면 다음과 같습니다.

  1. 멀티태스킹(Multitasking) 또는 멀티프로그래밍(Multiprogramming)은 하나의 프로세스가 계속 CPU를 점유하는 것을 막으면서, 여러 프로세스를 동시에 실행시키는 것처럼 만드는 기법을 사용한다. 이를 통해 CPU 사용을 최대화하고, 시간 자원을 여러 프로세스에 균등하게 분배할 수 있다. 이 시간 자원을 균등하게 배분하는 것을 시분할(Time Sharing) 기법이라고 부른다.
  2. 프로세스 간 작업을 전환하는 것을 컨텍스트 스위칭(Context Switching)이라고 부른다.
  3. 컨텍스트 스위칭은 커널의 도움을 필요로 하기 때문에 리소스가 든다.
  4. 컨텍스트 스위칭은 인터럽트 기반으로 동작한다. 인터럽트가 발생하면 CPU는 현재 진행 중인 작업을 중단하고, 인터럽트가 발생했을 때 해야 할 일이 정의된 인터럽트 서비스 루틴(Interrupt Service Routine)을 수행한다.

 

 

PCB - 조리 중인 음식 목록을 어딘가에 적어두자

PCB
©thenounproject

 

그날 이후로 CPU는 여러 주문이 동시에 들이닥치면 조금씩 번갈아가면서 조리를 시작했습니다. 덕분에 주문이 몰려드는 점심시간에도 고객들에게 어느 정도 균등한 속도로 음식을 제공할 수 있었죠. 하지만 CPU 입장에서는 앉은자리에서 작업대가 계속 교체되니, 점점 자기가 만들고 있는 요리가 무엇인지 헷갈리기 시작합니다.

 

“내가 무슨 요리 하고 있었더라? 내가 패티를 구웠었던가? 아니면 내가 빵을 위에 얹었나?”

 

PCB
©thenounproject

 

커널은 결국 현재 들어온 주문들을 주문표로 적어서 관리하기로 합니다[1]. 그리고 CPU에게도 도움이 되도록 현재 작업대에서 조리 중이었던 상태와 함께, 어떤 부분부터 다시 조리를 계속하면 되는지를 기록해놓았죠[2]. 덕분에 조리 도중에 작업대가 바뀌더라도 CPU는 까먹지 않고 조리를 이어서 해 나갈 수 있게 되었습니다.

 

PCB
©thenounproject

 

하지만 CPU가 동시에 여러 음식을 만드는 것처럼 보인다고 해도, 실제로는 한 번에 하나의 요리를 처리할 수밖에 없었습니다. 그래서 커널은 현재 CPU가 어떤 주문을 처리하고 있는지를 정확히 구분하기 위해, 주문표에 임시로 4가지의 조리 상태를 추가적으로 기록해두기로 했습니다[3].

 

그렇게 방금 막 주문이 들어온 경우[4], 그리고 작업대가 차려져서 CPU의 손을 기다리는 경우[5], CPU가 현재 조리 중인 경우[6], 그리고 조리가 끝난 경우[7]를 구분하여 상태를 적어놓기로 했죠.

 

이번 섹션에서 비유한 내용을 설명으로 나타내면 다음과 같습니다.

  1. 멀티태스킹에서 각 프로세스의 정보를 저장하고 관리하기 위해 커널은 PCB(Process Control Block)를 이용한다.
  2. 컨텍스트 스위칭이 일어나면 현재까지 실행된 코드와 함께 다음으로 실행할 코드 주소를 나타내는 프로그램 카운터(Program Counter)를 PCB의 레지스터에 저장한다.
  3. PCB에는 프로세스 상태(Process State)를 저장함으로서 현재 프로세스의 처리 상태를 5개로 관리하고, 상태 전이도로 나타낼 수 있다. wait 단계는 추후 설명한다.
  4. new는 프로세스를 위한 PCB가 생성되었지만 아직 메모리에는 올라가 있지 않은 상태를 나타낸다.
  5. ready는 프로세스가 CPU를 점유하고 사용이 가능한(dispatch) 상태를 나타낸다.
  6. running는 프로세스가 현재 CPU를 점유하여 작업을 처리 중인 상태를 나타낸다.
  7. terminated는 프로세스가 작업을 완료하여 메모리 자원을 반납하고 PCB가 삭제된 상태를 나타낸다.

 

 

I/O 처리 - 주문받는 도중에도 요리를 할 순 없을까

고객의 응대는 항상 친절하게 기다리는 것이 커널의 원칙이었지만, 이러한 친절은 주문 관리 입장에서 독이 되기도 했습니다. 어떨 때는 조리 도중 고객에게 대답을 들어야 하는 경우가 있었기 때문입니다.

 

I/O 처리
©thenounproject

 

“1834번 고객님, 주문 중에서 확실하지 않은 부분이 있어 여쭤봅니다. 소스는 머스터드와 케첩 중에서 무엇으로 드리면 될까요?”

 

“아… 저… 그… 흠… 아니… 음… 쓰읍… 음… 어떡하지…잠시만여…“

 

주문들은 휘몰아치고 커널이 할 일은 많은데, 이렇게 대답을 망설이는 손님들이 있었기 때문입니다. 이처럼 커널의 입장에서는 손님들의 의견을 들어주러 나가는 것은 시간이 상당히 오래 걸리는 작업이었습니다. 주문 관리 면에서도 이는 비효율적이었습니다. 해당 고객의 요구 사항을 다 듣기 전까지는 다른 요리까지 신경을 쓰며 관리하기가 쉽지 않았기 때문입니다.

 

“바빠 죽겠는데, 대답을 망설이는 손님들이 많으니… 뭐 어떻게 좋은 방법 없을까?”

 

I/O 처리
©thenounproject

 

커널은 우선 고객 요구사항이 발생할 때에는 조리를 계속할 수 없기 때문에, 주문표의 조리 상태에 별도의 대기 상태를 새로 추가하기로 했습니다[1]. 이 상태는 현재 고객 호출이 발생해서 대답을 들으러 갔으니, 별도의 응답이 있을 때까지 추가적으로 조리를 하지 말라는 뜻이었죠.

 

I/O 처리
©thenounproject

 

커널은 우선 주기적인 시간을 두고 카운터에 나가서 요구 사항이 있는 고객이 있는지를 확인하는 방법을 생각해보았습니다[2]. 나쁘진 않은 방법이었지만, 그런 고객이 없을 때에는 불필요하게 동선 낭비가 생기기 마련이었습니다. 그래서 커널은 호출 벨을 두는 방법을 선택했습니다[3]. 고객이 요구 사항이 있을 때에만 커널을 호출해 요구사항을 전달하니, 이전 방식보다는 효율적이었습니다.

 

이번 섹션에서 비유한 내용을 설명으로 나타내면 다음과 같습니다.

  1. 프로세스 상태에서 I/O 작업처럼 시간이 오래 걸리는 작업은 별도의 waiting 상태로 둔 후 I/O 이벤트가 발생하기를 기다린다. 이벤트가 발생하면 인터럽트를 발생시킨 후 다시 PCB 상태를 ready로 전환하여 CPU가 처리 가능한 상태로 만든다.
  2. 폴링(Polling)은 특정 주기마다 I/O 버퍼에 입출력이 쌓여있는지를 확인하는 방법이다.
  3. OS는 I/O 이벤트가 발생할 때마다 인터럽트를 발생시킨다.

 

 

IPC - 다른 작업대에 음식을 넘겨줄 순 없을까?

IPC
©thenounproject

 

여러 주문을 동시에 처리하고, 고객 요구사항도 잘 들어주다 보니 가게는 점점 더 번창했습니다. 그래서 커널은 세트 메뉴를 추가해보기로 했습니다. 햄버거와 감자튀김, 음료수를 하나로 묶어서 제공하는 것이었죠. 그나저나 여태까지 세트 메뉴가 없었다니, 고객들이 식사할 때 상당히 목이 막혔겠는걸요.

 

아무튼 새롭게 세트 메뉴를 기획했지만, 작업대 규칙이 걸림돌이 되었습니다. 하나의 작업대에서는 하나의 요리를 하기로 약속했는데, 세트 메뉴는 요리들이 여러 작업대 사이를 오가야 했기 때문이죠. 감자튀김 작업대에서 만들어진 감자튀김, 음료수 작업대에서 만들어진 음료수를 햄버거 작업대로 이동시켜야 했습니다[1].

 

IPC
©thenounproject

 

고민하던 커널은 두 가지 방법을 마련했습니다. 우선 세트 메뉴에 한해서는 특별히 각 요리를 다른 작업대에 공유할 수 있는 임시 작업대를 마련해주기로 한 거죠[2]. 임시 작업대에는 해당 세트 메뉴와 관련 있는 작업대에서는 특별한 제약 없이 접근할 수 있게 만들어주었습니다.

 

감자튀김이나 콜라를 공유 작업대에 올려놓은 후, 햄버거 작업대에서 이를 가져오기만 하면 세트 메뉴가 완성되었습니다.

 

또 다른 방법으로는 커널 자기 자신에게 전달할 요리와 목적지를 전달해주면, 자기가 시간이 날 때 순서대로 갖다 주겠다고 했습니다[3]. 아무래도 꼼꼼한 성격의 커널은 이 방식을 더 선호할 것 같군요.

 

이번 섹션에서 비유한 내용을 설명으로 나타내면 다음과 같습니다.

  1. 프로세스 간 자원 공유 기법을 IPC(Inter-Process Communication)라고 부른다.
  2. 공유 메모리(Shared Memory): 여러 프로세스에서 공용으로 접근할 수 있게 보안 규칙에 일시적 예외를 둔 메모리를 제공하는 방법
  3. 메시지 패싱(Message Passing): 커널의 메시지 큐에 메시지와 목적지를 전달하면, 커널이 대신 전달해주는 방법

 

 

쓰레드 - 비슷한 요리를 만들 때에도 작업대를 꼭 따로 두어야 할까?

쓰레드
©thenounproject

 

커널이 IPC를 마련해준 덕분에 세트 메뉴도 판매가 시작되었습니다. 그렇게 식당이 잘 되다 보니, 가끔씩은 단체 주문도 들어오게 되었습니다.

 

이번 단체 주문은 햄버거 100개를 한꺼번에 주문했네요. 그런데 각 요리마다 작업대를 새로 깔려고 하는게 여간 시간이 오래 걸리는 일이 아니었습니다. 100개의 작업대를 순서대로 깔다가 지친 커널은 다시 고민에 빠지게 됩니다.

 

“어차피 레시피랑 재료는 같은데, 한 작업대에서 같은 요리를 여러 개 만들 수 있지 않을까?” [1]

 

비슷한 작업을 반복하는 거면 굳이 새 작업대를 깔 필요도 없었고, 한 작업대에서 음식을 조리하니 시간도 절약되었죠.

 

쓰레드
©thenounproject

 

뭔가 깨달은 커널은 새 요리사를 한 명 더 고용했습니다. 이제 주방에는 두 명의 요리사가 있습니다. 커널은 두 요리사에게 하나의 작업대만 갖다주며 이야기합니다.[2]

 

“햄버거를 100개 만들어야 하는데, 어차피 레시피랑 재료가 같잖아? 작업대를 100개 깔면 시간이 오래 걸리니까 이번에는 한 작업대에서 각자 50개씩 햄버거를 만들도록 해.” [3]

 

이 명령을 들은 CPU들은 요리해야 할 양을 절반씩 나누어 만들기 시작합니다. 뭐, 커널의 말대로 레시피랑 재료가 같으니 그저 각자 조리 중인 햄버거가 섞이지 않게만 조심하면 문제가 없을 것 같네요. 친절한 커널은 CPU를 배려해서, 하나의 작업대에서 여러 요리를 만들 때에도 주문표에 각 요리사들이 어디까지 조리를 했는지를 적어둡니다[4].

 

이번 섹션에서 비유한 내용을 설명으로 나타내면 다음과 같습니다.

  1. 쓰레드(Thread)는 프로세스 내에서 실행되는 CPU 스케쥴링의 기본 단위이다. 하나의 프로세스 내에서 여러 개의 쓰레드가 실행될 수 있고 이를 멀티 쓰레드 라고 부른다.
  2. 각 쓰레드는 자기 자신만의 실행 상태를 가질 수 있기 때문에, 서로 다른 CPU에서도 동작할 수 있다. 이 덕분에 여러 CPU를 단일 회로로 통합한 멀티 코어 프로세서를 이용하면 물리적으로 병렬 처리가 가능하다.
  3. 기본적으로 하나의 프로세스 내에서 실행되는 각 쓰레드는 프로세스의 메모리를 공유한다. 하지만 쓰레드 별로 실행 중인 코드 위치와 컨텍스트가 다를 수 있기 때문에, 프로그램 카운터는 따로 저장하고 스택은 분할해서 사용한다.
  4. 각 쓰레드의 정보를 저장하기 위해 커널은 쓰레드 제어 블록(TCB, Thread Control Block)을 만들어 PCB에 저장한다.

 

 

동기화 문제 - 함께 작업하는 부분에서 문제가 생길 수 있다

동기화 문제
©thenounproject

 

오늘도 단체 주문이 들어왔습니다. 여느 때처럼 커널은 두 명의 요리사에게 하나의 작업대에서 단체 주문을 처리하라고 명령합니다. 하지만 CPU가 잔꾀를 부려봅니다.

 

“이봐, 각자 햄버거를 50개씩 작업하지 말고 오늘은 내가 빵을 쌓을 테니 너가 패티를 쌓아보는 방법으로 햄버거를 조립해보자구.”

 

처음에는 얼추 합이 맞았습니다. 하지만 두 사람의 작업 속도가 조금씩 다르다 보니 손발이 꼬이기 시작합니다. 참깨빵 위에 순쇠고기 패티 두 장을 올려야 하는데, 한 사람이 패티를 쌓는 도중에 다른 사람이 그 위에 다른 햄버거에 들어갈 패티를 쌓았습니다. 작업대가 바뀌는 와중에 패티를 잘못 쌓고, 내가 쌓아야 하는 것에 상대방이 또 쌓고… 두 사람의 호흡이 맞지 않자, 해당 작업판에서 만드는 모든 햄버거가 엉망이 되기 시작했습니다[1].

 

커널은 깜짝 놀라 주방으로 달려왔습니다. 아무리 작업을 빠르게 한다 해도, 엉망인 햄버거가 나온다면 아무 소용이 없었기 때문입니다. 결국 커널은 레시피 문구에 커다랗게 주의사항을 적어놓습니다.

 

“햄버거를 조립할 때에는 반드시 한 사람이 하나만 담당하기! 두 명이 동시에 접근해야 하는 게 있다면, 한 사람 작업이 끝날 때까지 기다리기!” [2]

 

동기화 문제
©thenounproject

 

이렇게 햄버거의 조립 순서를 한 사람으로 고정하고 나서부터는 더 이상 패티가 넘치거나 부족한 문제가 생기지 않았습니다.

 

드디어 OS 레스토랑 은 손님이 많아도, 고객이 중간에 호출해도, 요리사가 여러 명이어도 헷갈리지 않고 끊임없이 고객들에게 요리를 제공할 수 있었다고 합니다.

 

이번 섹션에서 비유한 내용을 설명으로 나타내면 다음과 같습니다.

  1. 쓰레드는 프로세스에 비해 성능 상 이점이 있지만, 전역 변수 등 메모리를 공유하는 부분에 있어서는 불일치 문제가 발생할 수 있는데 이를 해결하는 방법을 동기화(Synchronization) 기법이라고 부른다.
  2. 메모리 상 불일치가 발생할 수 있는 코드를 임계 영역(Critical Section)이라 부르고, 한 순간에 하나의 쓰레드가 접근 가능하게 만드는 방법(Lock) 등으로 코드의 잘못된 실행을 막는다.

 

 

마무리

OS 운영체제

 

이번 글은 여기까지입니다. 어떻게 이해가 잘 되었을지 모르겠네요. 현실 예시에 맞추어 설명하려다 보니 약간 억지스러운(?) 부분도 없잖아 있지만, 그래도 여기까지 읽었으면 CPU의 원리와 프로세스, 쓰레드에 대한 기초 개념을 한 번 훑은 것입니다.

 

비유를 들며 설명한 글이기 때문에 일부 정확하지 않거나 생략된 개념들이 있습니다. 그렇기 때문에, 보다 자세한 설명은 각 섹션 아래에 언급한 설명의 키워드를 직접 검색해보시면서 알아보시는 것을 추천드립니다. 아무튼 이번 글이 대략적인 개념 잡기에는 도움이 되었으면 좋겠습니다. 혹시라도 잘못된 비유가 있거나 하면 알려주세요.

댓글 0

재그지그의 개발 블로그

'재그지그’라는 필명으로 활동하고 있는 주니어 프론트엔드 개발자. 지식을 공유하는 것을 좋아해서 개인적으로 개발 블로그(https://wormwlrm.github.io)를 운영 중이며, 주로 프론트엔드, 디자인, UI•UX를 주제로 포스트를 작성하고 있다.

같은 분야를 다룬 글들을 권해드려요.

요즘 인기있는 이야기들을 권해드려요.

일주일에 한 번!
전문가들의 IT 이야기를 전달해드려요.

[구독하기] 버튼을 누르면 개인정보 처리방침에 동의됩니다.

일주일에 한 번! 전문가들의 요즘IT 이야기를 전달해드려요.

[구독하기] 버튼을 누르면 개인정보 처리방침에 동의됩니다.