node.js - NodeJS异步机制的疑惑
PHP中文网
PHP中文网 2017-04-17 16:12:59
0
7
541

问题描述:大家都知道nodejs因为其异步编程和事件机制而被大家津津乐道,但是最近在学习nodejs时对nodejs的异步不是很理解。都说nodejs是单进程单线程的,但是它的异步处理又给人的感觉是多线程的,比如下面的例子:

var fs = require("fs");

var data = fs.readFileSync('input.txt');//同步等待执行,这必然是单线程

console.log(data.toString());
console.log("程序执行结束!");

但是,它还有异步方式是这样处理:

var fs = require("fs");

fs.readFile('input.txt', function (err, data) {//异步执行,这个地方没有等待执行结束就已经打印了"程序执行结束",然后打印data数据
    if (err) return console.error(err);
    console.log(data.toString());
});

console.log("程序执行结束!");

希望大神们帮忙解释一下,总感觉它异步是多线程方式,而nodejs确实单进程单线程的?

PHP中文网
PHP中文网

认证高级PHP讲师

모든 응답(7)
巴扎黑

노드는 단일 스레드입니다. 이 스레드는 메인 스레드로 이해될 수 있습니다. 비동기가 발생하면 파일을 읽는 비동기 작업이 플랫폼(파일 IO)에 따라 선택되는 기본 libuv로 전달됩니다. 스레드 풀, 네트워크 IO를 사용하고 Linux는 epoll을 사용하고 Windows는 IOCP를 사용합니다. 비동기 작업이 완료된 후에는 js 코드만 실행되고 이벤트 큐에 들어가 이벤트 폴링을 수행합니다. 메인 스레드가 유휴 상태일 때 처리를 위해 출력됩니다.

大家讲道理

실제로 질문자는 인터넷에서 node event loop의 메커니즘을 검색해 보면 노드의 비동기 작업이 어떻게 작동하는지 이해할 수 있습니다.
노드 하단에는 I/O, 네트워크 요청 등 c/C 와 상호 작용하는 libuv라는 것이 있습니다.

이벤트 루프의 메커니즘에 대해 간략하게 이야기해 볼까요? 질문자는 온라인에서 검색해서 자세히 이해하는 것이 가장 좋습니다.

예를 들어, 귀하가 작성한 예는 다음과 같습니다.

으아아아

소개의 편의를 위해 일련번호를 표시해 두었습니다. 작동 메커니즘은 대략 다음과 같습니다.
프로그램은 1으로 실행됩니다. 인용한 후 계속 진행하면 2에 도달하면 노드는 이것이 비동기 I/O 작업임을 알게 됩니다. 우리 모두 알고 있듯이 I/O 작업은 단일 스레드이므로 실제로는 원하지 않습니다. 이를 위해 libuv에 넘겨지고 4로 표시된 곳에 콜백 함수가 제공됩니다. 이 콜백은 c/C 의 하위 레이어가 호출된 후에 호출됩니다. 처리됨.
그런데 libuv에 넘겨주는 과정에서 프로그램이 계속 아래로 흘러 3 인쇄할 수 있는 위치에 도달하게 됩니다.
이것이 인쇄 결과를 먼저 본 다음 파일 내용을 보는 이유입니다.

이것은 아마도 Event Loop의 작동 메커니즘일 것입니다. 노드는 항상 어려운 작업을 다른 사람에게 맡기고 다른 사람이 완료된 후에만 콜백을 실행합니다. 따라서 노드는 많은 계산 작업을 수행하는 데 적합하지 않습니다. 예를 들어 while(true){}을 작성하면 전체 프로그램이 중단됩니다.
Node는 작은 계산과 높은 동시성을 좋아하는데, 처리 측면에서 정말 장점이 있어서 받아들이지 않을 수 없습니다.

刘奇

제 가설을 말씀드리겠습니다.
파일을 읽을 때 NODEJS가 운영 체제에 읽기 신호(아마도 다른 것을 보낼 수도 있음, 원리는 동일)를 보낸다고 가정해 보겠습니다. 기타 사항(운영 체제가 파일 읽기를 완료할 때까지 기다릴 필요가 없습니다. 이는 비동기식입니다.) 운영 체제가 읽기를 완료한 후 NodeJs에 이벤트를 보내면 파일이 읽혔음을 알고 콜백합니다. 콜백 함수를 통한 실행 결과.
NodeJs는 파일을 읽는 대기 시간을 차단하지 않고 다른 작업을 수행하는 데 사용합니다.

巴扎黑

아래가 파일 읽기가 끝날 때까지 기다렸다가 다음 程序执行结束을 출력한다면, 이것과 동기화 모드 사이에 차이가 있는 걸까요...
nodejs은 싱글 쓰레드죠, 그렇죠, 그 이유는 메인 프로세스가 끝난 후에 비동기 프로세스가 수행되기 때문에 다음과 같이 먼저 출력된다.

左手右手慢动作

노드에 이벤트 대기열이 있습니다

Ty80

이벤트 루프를 확인하세요. 타이머의 함수는 이벤트 큐에 배치되고 이벤트 큐에 배치된 순서대로 다음 루프에서 실행됩니다.

Ty80

Node의 엔진은 단일 스레드이지만 하단에서 호출하는 libuv는 그렇지 않습니다. Linux에서 네트워크 요청에 대해 libuv가 사용하는 epoll은 자체 스레드 풀을 구축하고 Windows에서 iocp를 사용합니다.

최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿