[node.js] Node.js 이벤트 루프 틱이란 정확히 무엇입니까?

저는 Node.js 아키텍처의 내부에 대해 더 많이 알고 있으며, “이벤트 루프의 다음 틱”또는 함수 nextTick () 에서와 같이 많이 나오는 용어는 “틱” 입니다.

내가 보지 못한 것은 정확히 “틱”이 무엇인지에 대한 확실한 정의입니다. 다양한 기사 ( 예 :이 기사)를 기반으로 한 개념을 머릿속에 모을 수 있었지만 그게 얼마나 정확한지 잘 모르겠습니다.

Node.js 이벤트 루프 틱에 대한 정확하고 자세한 설명을 얻을 수 있습니까?



답변

JavaScript는 단일 스레드이지만 노드의 모든 I / O 및 네이티브 API 호출은 비동기 (플랫폼 별 메커니즘 사용)이거나 별도의 스레드에서 실행됩니다. (이것은 모두 libuv를 통해 처리됩니다.)

따라서 소켓에서 사용할 수있는 데이터가 있거나 기본 API 함수가 반환되면 방금 발생한 특정 이벤트에 관심이있는 JavaScript 함수를 호출하는 동기화 된 방법이 필요합니다.

경합 조건, 비 원자 메모리 액세스 등과 같은 일반 다중 스레드 응용 프로그램에서 발생하는 것과 동일한 이유로 네이티브 이벤트가 발생한 스레드에서 JS 함수를 호출하는 것은 안전하지 않습니다.

그래서 우리가하는 일은 스레드로부터 안전한 방식으로 이벤트를 큐에 배치하는 것입니다. 지나치게 단순화 된 의사 코드에서 다음과 같습니다.

lock (queue) {
    queue.push(event);
}

그런 다음 메인 자바 스크립트 스레드로 돌아가서 (하지만 C 쪽에서는) 다음과 같이합니다.

while (true) {
    // this is the beginning of a tick

    lock (queue) {
        var tickEvents = copy(queue); // copy the current queue items into thread-local memory
        queue.empty(); // ..and empty out the shared queue
    }

    for (var i = 0; i < tickEvents.length; i++) {
        InvokeJSFunction(tickEvents[i]);
    }

    // this the end of the tick
}

while (true)(실제로 노드의 소스 코드에 존재하지 않는,이 순전히 예시)을 나타내는 이벤트 루프 . 내부 for는 큐에 있던 각 이벤트에 대해 JS 함수를 호출합니다.

이것은 틱입니다. 외부 이벤트와 관련된 0 개 이상의 콜백 함수를 동 기적으로 호출하는 것입니다. 큐가 비워지고 마지막 함수가 반환되면 틱이 끝납니다. 처음 (다음 틱)으로 돌아가서 JavaScript가 실행되는 동안 다른 스레드에서 큐에 추가 된 이벤트를 확인합니다 .

무엇을 대기열에 추가 할 수 있습니까?

  • process.nextTick
  • setTimeout/setInterval
  • I / O (에서 재료 fs, net등)
  • crypto암호화 스트림, pbkdf2 및 PRNG와 같은 프로세서 집약적 인 기능 (실제로는 …)
  • libuv 작업 대기열 을 사용하여 동기식 C / C ++ 라이브러리 호출을 비동기식으로 만드는 모든 기본 모듈


답변

JavaScript를 처음 접하는 사람들을위한 간단한 대답 :

가장 먼저 이해해야 할 것은 JavaScript가 “단일 스레드 환경”이라는 것입니다. 이것은 단일 스레드의 “이벤트 루프”에서 코드 블록을 한 번에 하나씩 실행하는 JavaScript의 동작을 나타냅니다. 아래에는 Kyle Simpson의 책 ydkJS에서 가져온 이벤트 루프의 기본 구현이 있으며 그 이후에 설명이 있습니다.

// `eventLoop` is an array that acts as a queue (first-in, first-out)
var eventLoop = [ ];
var event;

// keep going "forever"
while (true) {
    // perform a "tick"
    if (eventLoop.length > 0) {
        // get the next event in the queue
        event = eventLoop.shift();

        // now, execute the next event
        try {
            event();
        }
        catch (err) {
            reportError(err);
        }
    }
}

첫 번째 while 루프는 이벤트 루프를 시뮬레이션합니다. 틱은 “이벤트 루프 대기열”에서 이벤트를 대기열에서 빼고 해당 이벤트를 실행하는 것입니다.

이벤트의 대기열에서 빼기 및 실행에 대한 자세한 설명은 ‘Josh3796’의 응답을 참조하십시오.

또한 JavaScript에 대한 깊은 이해에 관심이있는 사람들을 위해 Kyle Simpson의 책을 읽는 것이 좋습니다. 완전 무료이며 오픈 소스이며 다음 링크에서 찾을 수 있습니다 :
https://github.com/getify/You-Dont-Know-JS

내가 참조한 특정 섹션은 https://github.com/getify/You-Dont-Know-JS/blob/2nd-ed/sync-async/ch1.md 에서 찾을 수 있습니다.


답변

이벤트 루프 틱의 매우 간단하고 짧은 방법은 다음과 같습니다.

큐에 대한 요청 세트가 처리 될 때 작업 완료를 나타내는 틱이 시작되는 노드 내부 메커니즘에서 사용됩니다.


답변