neverlish's blog
aboutgithub

Node.js는 싱글스레드인가?

면접에서 nodejs 관련해서 나오는 단골질문 "node.js는 싱글스레드인가요?" 에 대한 나름의 생각을 정리한다.

thread란?

스레드(thread)는 어떠한 프로그램 내에서, 특히 프로세스 내에서 실행되는 흐름의 단위를 말한다.
일반적으로 한 프로그램은 하나의 스레드를 가지고 있지만, 프로그램 환경에 따라 둘 이상의 스레드를 동시에 실행할 수 있다.
이러한 실행 방식을 멀티스레드(multithread)라고 한다.

출처: 위키백과

single thread란?

멀티 스레드는, 하나의 프로세스에서 둘 이상의 스레드를 동시에 실행하는 것이다.

하나의 프로세스에서 하나의 스레드만 활용하면, CPU 등의 자원을 완전히 사용하지 못하게 된다. 그래서 여러 개의 스레드를 실행하여 성능을 높이는 것이다. 반면에, 여러 스레드에서 병렬로 작업이 수행될때 예상치 못한 부작용이 생길 수 있다. 순서 보장이 되지 않는다던가, 같은 값을 동시에 변경하여 예상치 못한 데이터 꼬임이 생기는 등의 현상이 발생할 수 있다.

싱글 스레드란, 하나의 프로세스에서 하나의 스레드를 실행하는 것이다. 싱글 스레드를 채택하면 멀티 스레드처럼 작업전환 관련한 이슈는 없지만, 데이터를 효율적으로 사용하기 위한 방안을 강구해야 한다. 예를 들어, 작업의 병렬 수행을 위한 무언가 다른 장치가 필요하다.

node.js 에 대해서

node.js 공식홈페이지(https://nodejs.org/ko/about)에서는, node.js에 대해 아래와 같이 설명한다.

비동기 이벤트 주도 JavaScript 런타임으로써 Node.js 는 확장성 있는 네트워크 애플리케이션을 만들 수 있도록 설계되었습니다.
이는 오늘날 OS 스레드가 일반적으로 사용하는 동시성 모델과는 대조적입니다.
스레드 기반의 네트워크는 상대적으로 비효율적이고 사용하기가 몹시 어렵습니다.
게다가 잠금이 없으므로 Node.js 의 사용자는 프로세스의 교착상태에 대해서 걱정할 필요가 없습니다.
Node.js 에서 I/O를 직접 수행하는 함수는 거의 없으므로 프로세스는 결과 블로킹 되지 않습니다.
아무것도 블로킹 되지 않으므로 Node.js 에서는 확장성 있는 시스템을 개발하는 게 아주 자연스럽습니다.

기존의 웹서버 런타임에서는 오래 걸리는 작업(I/O, 네트워크 등)을 위해 스레드를 점유했고, 많은 스레드를 관리하는 것이 웹서버의 주요한 역할이었다. node.js는 기존 웹 서버들과는 다른 방식을 채택했다.

node.js는 싱글스레드인가?

최초의 javascript 는 브라우저에서 돌아가도록 만들어진 언어이다. 브라우저에서만 돌아가기 때문에 멀티스레드 환경은 고려되지 않았다.

node.js는 브라우저에서 아닌 환경에서도 js를 돌릴 수 있도록 고안된 "실행 환경"이다. node.js라는 런타임을 만들면서, 스레드를 활용하지 않고 비동기 I/O를 이용한 방식이 고안되었다.

멀티스레드의 장점과 싱글스레드의 장점을 모두 취하기 위한 접근 방식이다.

"node.js는 싱글스레드인가" 라는 질문에 대해서 명확한 답을 내리기는 어렵다. 이 질문에 대한 내 의견을 짧게 내보자면, 아래와 같다.

  • node.js는 싱글스레드가 아니다
  • node.js에서 자바스크립트 부분은 단일 스레드 환경에서 돌아간다.
  • 자바스크립트 부분은 단일 스레드이지만, node.js 에서 자바스크립트 이외의 부분은 멀티스레드이다.

js 부분은 단일 스레드이다.

비동기 작업 수행시 js 부분의 역할은 이벤트 루프에 작업을 던지는 것이다. 이후에는 이벤트 루프에서 알아서 하는 것이다. js 의 메인 스레드는 논블로킹으로 계속 돌아갈 수 있다.

js 이외의 부분은 멀티스레드이다.

자바스크립트 부분은 단일 스레드이지만, node.js 에서 자바스크립트 이외의 부분은 멀티스레드이다. Event Loop이다. 이벤트 루프는 내부적으로 여러 개의 스레드를 점유하고, 병렬 처리를 수행한다. libuv 과 v8 엔진의 힘을 빌리고 있다. Event Loop 부분에 대해서는 자세하게 설명된 글이 있어 첨부한다.(https://velog.io/@dosomething/Node.js-%EC%9D%B4%EB%B2%A4%ED%8A%B8-%EB%A3%A8%ED%94%84Event-Loop)

node.js가 싱글스레드여서 얻는 장점

node.js는 싱글스레드이면서 병렬 작업을 수행할 수 있고, IO에 특장점이 있다. 때문에 아래와 같은 장점이 있다.

  • 멀티스레드 환경에서 고려해야 할 context switch를 고려하지 않아도 된다.
  • 실행시간이 오래 걸리는 I/O가 많은 프로그램에서, 비동기 처리의 강점을 보인다. 예를 들어 채팅 프로그램, 크롤링 서버 등이 있다.

References