백엔드 개발자들이 알아야할 동시성 3 — 쓰레드와 컨텍스트 스위치

Choi Geonu
4 min readJan 26, 2022

지금까지의 포스팅에선 병행성(Concurrency), 동기(Synchronous) / 비동기(Asynchronous), 블로킹(Blocking) / 논블로킹(Non-)Blocking에 대해서 알아보았습니다. 이제는 이러한 개념들 위해서 많은 소프트웨어들이 겪고있는 문제가 무엇이고 그 문제들에 대한 해결책으로 어떤 것들이 제시되고 있는지 알아보겠습니다.

쓰레드 (Thread)

이전 포스팅에선 쓰레드가 무엇인지에 대해서 정확하게 짚고 넘어가지 않았습니다. 이번 포스팅은 쓰레드에 대해서 간단히 이야기하며 시작하겠습니다.

우리가 가진 컴퓨터에 2개의 CPU가 있다고 하면 동시에 몇개의 작업을 처리할 수 있을까요?

당연히 2개의 작업을 처리할 수 있을것입니다. 하지만 우리는 하나의 컴퓨터에서 여러 작업을 수행하기를 원하죠.

만약 2개의 CPU에서 4개의 작업을 동시에 수행하는것 처럼 보이게 하려면 어떻게 할 수 있을까요?

위와 같이 여러개의 작업을 빠르게 번갈아가며 처리하면 CPU는 2개이지만 사용자는 4개의 작업이 동시에 수행되는 것 처럼 보이게 될 것 입니다. 이러한 하나의 Task 단위를 우리는 쓰레드라고 부르고, 이러한 원리로 우리가 IDE를 수행하면서 동시에 웹브라우저를 통해 웹사이트를 둘러볼 수 있는것입니다.

컨텍스트 스위칭

하나의 CPU가 여러 쓰레드를 번갈아 가며 처리하려면, 하나의 Thread에서 수행중인 동작을 멈추고 그 상태를 기억한 후 새로운 쓰레드로 이동해야 할 것 입니다. 이라한 일련의 과정을 우리는 컨텍스트 스위칭이라고 부릅니다. 컨텍스트 스위칭을 할 때 시스템에선 다음과 같은 작업이 발생하게 됩니다.

보기에는 간단해 보이지만 Register에서 Stack으로 약 7개 이상의 값을 옮기는 과정은 결코 가볍지 않습니다. 특히나 1초에 수백번씩 이런 일이 반복되는데 Thread가 많아진다면 이는 CPU 입장에선 너무나 부담스러운 일이 되게 될것입니다.

스택 사이즈 (Stack Size)

컴퓨터 과학 관점에서 보았을때 하나의 쓰레드는 하나의 스택을 의미하기도 합니다. 리눅스에서 하나의 스택은 얼마만큼의 메모리를 차지할까요? man pthread_create 에 따르면 x86_64기준 하나의 Stack은 2MB 정도의 메모리를 차지합니다.

┌─────────────┬────────────────────┐
│Architecture │ Default stack size │
├─────────────┼────────────────────┤
│i386 │ 2 MB │
├─────────────┼────────────────────┤
│IA-64 │ 32 MB │
├─────────────┼────────────────────┤
│PowerPC │ 4 MB │
├─────────────┼────────────────────┤
│S/390 │ 2 MB │
├─────────────┼────────────────────┤
│Sparc-32 │ 2 MB │
├─────────────┼────────────────────┤
│Sparc-64 │ 4 MB │
├─────────────┼────────────────────┤
│x86_64 │ 2 MB │
└─────────────┴────────────────────┘

이 상황에서 쓰레드를 1000개정도 생성한다면 메모리 4GB정도는 우습게 차지할 수 있는것입니다.

단순하게 생각해서 하나의 웹서버가 1000개의 요청을 처리하기 위해 무려 4GB 메모리를 사용해야 한다는 의미가 됩니다.

블로킹 & 동기 네트워킹 (Blocking & Synchronous Networking)

전통적으로 사용되는 블로킹 & 동기 네트워킹을 이용한 웹서버에서는 위 두가지 문제점을 모두 겪을 수 밖에 없습니다. 많은 요청을 처리하기 위해선 많은 쓰레드를 생성해야하고, 쓰레드가 많아질수로 컨텍스트 스위칭의 부담이 커지는 동시에 많은 메모리도 차지하게 됩니다.

이러한 문제점들을 해결하기 위해서 소프트웨어 엔지니어들은 많은 시도를 하고 있습니다. 다음 포스팅부터는 이러한 문제점들을 해결하기 위한 접근 방법이 어떤것들이 있는지 알아보도록 하겠습니다.

--

--