많은 사람들은 단일 스레드 NodeJS가 다중 스레드 백엔드와 어떻게 경쟁할 수 있는지 이해하지 못하는 것 같습니다.
그 이유를 알아내려면 Nodejs가 단일 스레드라는 것이 실제로 무엇을 의미하는지 이해해야 합니다.
JavaScript 자체는 원래 양식 검증, 응답 작성 등과 같은 간단한 작업을 수행하기 위해 만들어졌습니다. Node.js 제작자 Ryan Dahl이 JavaScript를 사용하여 서버측 코드를 작성할 수 있게 된 것은 2009년이 되어서였습니다.
멀티스레딩을 지원하는 서버측 언어는 스레드와 기타 스레드 지향 기능 간의 동기화를 위한 다양한 구조와 구성을 가지고 있습니다.
이러한 것들을 지원한다는 것은 JavaScript가 전체 언어를 변경해야 한다는 것을 의미하며 이는 JavaScript 제작자의 아이디어에 어긋납니다. 따라서 순수 JavaScript에서 멀티스레딩을 지원하기 위해 Dahl은 해결 방법을 만들어야 했습니다. 살펴보자!
Node.js는 어떻게 작동하나요?
Node.js는 이벤트 루프에 의해 처리되는 기본 스레드와 작업자 스레드 풀의 여러 보조 스레드라는 두 종류의 스레드를 사용합니다.
비차단 I/O 작업을 처리하기 위한 Event Loop Node.js의 메커니즘은 JavaScript가 단일 스레드임에도 불구하고 가능한 경우 작업을 시스템 커널로 오프로드합니다. JavaScript 작업이 스레드를 차단하면 이벤트 루프도 차단됩니다.
작업자 풀은 별도의 스레드를 생성하고 처리한 다음 작업을 동기적으로 실행하고 결과를 이벤트 루프에 반환하는 실행 모델입니다. 그런 다음 이벤트 루프는 해당 결과를 사용하여 제공된 콜백을 실행합니다.
기본적으로 작업자 풀은 비동기 I/O 작업(주로 시스템 디스크 및 네트워크와의 상호 작용)을 처리합니다. 일부 모듈은 fs(I/O 중심) 또는 crypto(CPU 중심)와 같은 즉시 사용 가능한 작업자 풀을 사용합니다. 작업자 풀은 libuv에서 구현되며, 이는 Node가 JavaScript와 C++ 간에 내부적으로 데이터를 전송해야 할 때 약간이지만 거의 무시할 수 있는 지연을 발생시킵니다.
이벤트 루프와 작업 풀의 의미를 이해한 후 다음 코드를 살펴보겠습니다.
위 코드에서는 이벤트를 동기적으로 기다릴 필요가 없습니다. 파일을 읽는 작업을 작업자 풀에 위임하고 결과와 함께 제공된 함수를 호출합니다. 작업자 풀에는 자체 스레드가 있으므로 파일을 읽는 동안 이벤트 루프가 정상적으로 계속 실행될 수 있습니다.
소개하겠습니다: Worker_threads
Node.js 10.5.0이 출시되면서 Worker_threads가 등장했습니다. JavaScript에서 간단한 멀티스레드 애플리케이션 생성을 지원합니다.
Worker_threads는 nodejs 모듈 패키지입니다. 스레드 작업자는 별도의 스레드에서 생성된 코드 조각(일반적으로 파일에서 가져옴)입니다.
스레드 작업자, 작업자 및 스레드라는 용어는 종종 같은 의미로 사용된다는 점에 유의하는 것이 중요합니다. 그들은 모두 같은 것을 가리킨다.
Node.js의 작업자 스레드는 무거운 JavaScript 작업을 수행하는 데 유용합니다. 스레드의 도움으로 Workers는 JavaScript 코드를 병렬로 쉽게 실행할 수 있어 더 빠르고 효율적입니다. 메인 스레드를 방해하지 않고 무거운 작업을 완료할 수 있습니다.
이전 버전의 Node.js에는 작업자 스레드가 도입되지 않았습니다. 따라서 시작하려면 먼저 Node.js를 업데이트하세요.
이제 다음과 같이 스레드를 구현하기 위해 두 개의 파일을 만듭니다.
파일 이름: Worker.js
const { WorkerData, parentPort } = require('worker_threads'); console.log(`${workerData}가 어떻게 대기업들과 함께 놀고 싶어하는지에 대한 글`); parentPort.postMessage({ 파일 이름: 작업자 데이터, 상태: '완료' })
파일 이름: index.js
const { Worker } = require('worker_threads'); const runSerice = (workerData) => { return new Promise((해결, 거부) => { const 작업자 = new Worker('./worker.js', { 작업자데이터 }); 작업자.on('메시지', 해결); 작업자.on('오류', 거부); 작업자.on('종료', (코드) => { if (코드 !== 0) accept(new Error(`작업자 스레드가 종료 코드 ${code}로 중지되었습니다`)); }); }); }; const 실행 = 비동기 () => { const result = wait runSerice('Tunde Ednut'); console.log(결과); }; run().catch((err) => console.error(err))
;