개요
개발할때 제일 많이 사용하는 언어는 Typescript다. Typescript로 Server를 만들려면 Node.js 런타임을 사용해서 구축을 해야하는데 Node.js는 싱글 스레드 기반이다.
싱글스레드가 그냥 스레드 하나만 있는것만 알지만 어떻게 동작이되는지 자세히 알지 못해서 정리를 하려고한다. 싱글스레드가 뭔지 알기위해서는 멀티스레드에 대해서도 알아야 더 알기 쉽다고 생각해서 정리를 하게됐다.
Thread란?
Thread는 프로세스가 할당받은 자원을 이용하는 실행의 단위로 한 프로세스 안에서 동작되는 여러 실행 흐름으로 프로세스 안에서 Heap, Data, Code 영역을 공유한다. 이때, 멀티스레드인 경우에는 해당 프로세스 영역들을 공유한다.
멀티스레드는 스레드 간의 자원을 공유하고 자원 생성과 관리의 중복성을 최소화해서 수행 능력을 올린다. 각각의 스레드는 독립적인 작업을 수행해야 하기 때문에 고유한 ThreadId, 프로그램 카운터, 레지스터 집합, 스택을 가지고 있다.
싱글스레드(Single Thread)
하나의 프로세스에서 오직 하나의 Thread로만 실행이 되면서 하나의 레지스터와 스택으로 표현을 할 수 있다.
싱글스레드(Single Thread)의 장점은?
- context switch 작업을 요구하지 않음.
- context switch는 여러 개의 프로세스가 하나의 프로세스를 공유할 때 생기는 작업으로 많은 비용을 필요로한다.
- 자원 접근에 대해서 동기화를 신경쓰지 않아도 된다.
- 여러 Thread가 프로세스의 자원을 공유할 경우에 각 Thread가 원하는 결과를 얻게 하려면 공용 자원에 대한 접근을 제어해야한다.
- Thread들이 동시에 같은 자원에 접근을 못하도록 제어를 해줘야하는데 난이도가 높댜.
- 위와 같은 점들을 볼 때 single thread는 위와 같은 작업을 할 필요가 없다.
- 단순 CPU를 사용하는 계산작업이면 single thread로 프로그래밍을 하는 것이 더 효율적이다.
- 두 개의 작업을 하나의 Thread로만 처리하는 경우와 두 개의 Thread로 처리하는 경우로 예시를 들어보면
- 후자의 경우는 짧은 시간에 두 개의 Thread를 번갈아가며 작업을 수행하고, 동시에 두 작업이 이루어지는 것처럼 느껴진다.
- 하지만 두 개의 Thread로 작업한 시간이 Single Thread로 작업한 시간보다 더 걸릴 수 있다.
- 그 이유는 Thread간의 Context Switching에 시간이 걸리기 때문이다.
- 정리를 해보자면 단순히 CPU를 사용하는 작업은 Single Thread가 Multi Thread보다 빠르다.
그럼 싱글스레드(Single Thread)의 단점은?
- 여러 개의 CPU 활용을 못함.
- 프로세서를 최대한 활용하려면 Cluster 모듈을 사용하거나 외부에서 여러 개의 프로그램 인스턴스를 실행시키는 방법을 사용해야한다.
- 이 때 고려할 점은 다수의 프로그램 인스턴스가 어떻게 상태를 공유할 것인지 생각을 해야한다.
- 단순하고 빠른 메모리 기반의 Redis가 좋은 고려 대상이지만 서버 프로그램 인스턴스끼리 상태를 공유를 최소화하거나 가능하면 공유하지 않는 쪽으로 설계하는 것이 바람직한 방법이다.
- Single Thread 모델은 에러 처리를 못하는 경우가 있음.
- Multi Thread 모델은 에러 발생 시 새로운 Thread를 생성해서 극복을하는 반면에 새로운 Thread 생성이나 생성은 됐지만 실행하지 않은 Thread 처리에 비용이 발생한다.
멀티스레드(Multi Thread)
Multi Thread는 CPU의 최대 활용을 위해서 프로그램의 둘 이상을 동시에 실행하는 것을 말한다. 이 작업은 Context Switching을 통해서 이뤄진다.
하나의 Thread에서 다음 Thread로 넘어가면서 Context Switching이 일어난다. 그리고, Switching이 일어나면서 부분적으로 조금씩 각각의 Thread에 작업을 종료한다.
멀티스레드(Multi Thread)의 장점은?
- 응답성
- 프로그램의 일부분인 Thread 중 하나가 중단되거나 긴 작업을 수행하더라도 프로그램의 수행이 계속 되면서 사용자에 대한 응답성이 증가한다.
- 즉, Multi Thread모델은 에러 발생 시 새로운 Thread를 생성해서 극복한다.
- 하지만 새로운 Thread나 생성은 됐지만 실행되지 않고 있는 Thread 처리에 비용이 발생한다. (Single Thread는 프로그램 일부분이 중단되거나, 에러 발생 시 프로그램이 멈춤.)
- 경제성
- 프로세스 내에 자원들과 메모리를 공유하기 때문에 메모리 공간과 시스템 자원 소모가 줄어든다.
- Thread간의 통신이 필요한 경우 쉽게 데이터를 주고 받는다.
- 프로세스의 Context Switching과 다르게 Thread간의 Context Switching은 캐시 메모리를 비울 필요가 없기 때문에 더 빠르다.
- 멀티프로세서의 활용
- 다중 CPU 구조에서는 각각의 Thread가 다른 프로세서에서 병렬로 수행될 수 있으므로 병렬성이 증가한다.
그럼 멀티스레드(Multi Thread)의 단점은?
- Context Switching과 동기화 등의 이유로 Single Core Multi Threading은 Thread 생성 시간이 오히려 오버헤드로 작용해서 Single Thread보다 느리다.
- 공유하는 자원에 동시 접근 시 프로세스와는 다르게 Thread는 Data와 Heap 영역을 공유하기 떄문에 어떤 Thread가 다른 Thread에서 사용 중인 변수나 자료구조에 접근해서 엉뚱한 값을 가지고 올 수 있으므로 동기화는 필수다.
- Multi Threading을 위해서는 운영체제의 지원이 필요.
- Multi Thread모델은 프로그래밍 난이도가 높으며, Thread 수만큼 자원을 많이 사용한다.