<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>event-loop on LaMelD</title><link>https://lameld.github.io/tags/event-loop/</link><description>Recent content in event-loop on LaMelD</description><generator>Hugo</generator><language>ko-KR</language><lastBuildDate>Thu, 17 Sep 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://lameld.github.io/tags/event-loop/index.xml" rel="self" type="application/rss+xml"/><item><title>1. 웹 개발 기초 지식</title><link>https://lameld.github.io/nestjs/ch-01/</link><pubDate>Thu, 17 Sep 2026 00:00:00 +0000</pubDate><guid>https://lameld.github.io/nestjs/ch-01/</guid><description>&lt;h2 id="11-nodejs"&gt;1.1. &lt;code&gt;Node.js&lt;/code&gt;&lt;/h2&gt;&#10;&lt;h3 id="111-단일-스레드에서-구동되는-논블로킹-io-이벤트-기반-비동기-방식"&gt;1.1.1. 단일 스레드에서 구동되는 논블로킹 I/O 이벤트 기반 비동기 방식&lt;/h3&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;멀티스레딩&#10;&lt;ul&gt;&#10;&lt;li&gt;여러 작업 요청이 한꺼번에 들어올 때, 각 작업을 처리하기 위한 스레드를 만들고 할당하는 방식&lt;/li&gt;&#10;&lt;li&gt;속도가 빠르다.&lt;/li&gt;&#10;&lt;li&gt;공유 자원의 관리가 힘들다.&lt;/li&gt;&#10;&lt;li&gt;스레드가 늘어남에 따라 메모리를 소모하여 메모리 관리가 중요하다.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;Node.js&lt;/code&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;어플리케이션 단에서는 단일 스레드에서 작업을 처리&lt;/li&gt;&#10;&lt;li&gt;백그라운드에서는 스레드 풀을 구성해 작업을 처리&lt;/li&gt;&#10;&lt;li&gt;웹 서버를 운용할 때는 CPU 코어를 순산해서 관리하므로 실제 작업은 여러 개의 코어에서 별개로 처리&lt;/li&gt;&#10;&lt;li&gt;들어온 작업을 앞의 작업이 끝날 때까지 기다리지 않고(non-blocking) 비동기로 처리&lt;/li&gt;&#10;&lt;li&gt;입력은 하나의 스레드에서 받지만 순서대로 처리하지 않고 먼저 처리된 결과를 이벤트로 반환해주는 방식 사용&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="12-이벤트-루프"&gt;1.2. 이벤트 루프&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;이벤트 루프는 시스템 커널에서 가능한 작업이 있다면 그 작업을 커널에 이관한다.&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;Javascript&lt;/code&gt;가 단일 스레드 임에도 불구하고 &lt;code&gt;Node.js&lt;/code&gt;가 논블로킹 I/O 작업을 수행할 수 있도록 해주는 핵심 기능이다.&lt;/li&gt;&#10;&lt;li&gt;이벤트 루프의 6 단계&#10;&lt;ol&gt;&#10;&lt;li&gt;타이머 단계&lt;/li&gt;&#10;&lt;li&gt;대기 콜백 단계&lt;/li&gt;&#10;&lt;li&gt;유휴, 준비 단계&lt;/li&gt;&#10;&lt;li&gt;폴 단계 - 수신: 연결, 데이터 등&lt;/li&gt;&#10;&lt;li&gt;체크 단계&lt;/li&gt;&#10;&lt;li&gt;종료 콜백 단계&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h3 id="121-타이머-단계"&gt;1.2.1. 타이머 단계&lt;/h3&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;타이머 단계의 큐에는 &lt;code&gt;setTimeout&lt;/code&gt;이나 &lt;code&gt;setInterval&lt;/code&gt;과 같은 함수를 통해 만들어진 타이머들을 큐에 넣고 실행한다.&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;now - registeredTime ≥ delta&lt;/code&gt;인 타이머들이 큐에 들어간다.&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;delta&lt;/code&gt;는 &lt;code&gt;setTimeout(() =&amp;gt; {}, delta)&lt;/code&gt;와 같이 타이머가 등록된 시각에 얼만큼 시간이 흐른 후 동작해야 하는지를 나타내는 값이다.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h3 id="122-대기-콜백-단계pending-callback-phase"&gt;1.2.2. 대기 콜백 단계(pending callback phase)&lt;/h3&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;대기 단계의 큐에 들어 있는 콜백들은 현재 돌고 있는 루프 이전의 작업에서 큐에 들어온 콜백이다.&lt;/li&gt;&#10;&lt;li&gt;TCP 핸들러 내에서 비동기의 쓰기 작업을 한다면, TCP 통신과 쓰기 작업이 끝난 후 해당 작업의 콜백이 큐에 들어간다. 또 에러 핸들러 콜백도 큐로 들어오게 된다.&lt;/li&gt;&#10;&lt;li&gt;타이머 단계를 거쳐 대기 콜백 단계에 들어오면, 이전 작업들의 콜백이 &lt;code&gt;pending_queue&lt;/code&gt;에서 대기 중인지 검사한다. 만약 실행 대기 중이라면 시스템 실행 한도에 도달할 때까지 꺼내어 실행한다.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h3 id="123-유휴-준비-단계idle-prepare-phase"&gt;1.2.3. 유휴, 준비 단계(idle, prepare phase)&lt;/h3&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;유휴 단계는 틱마다 실행된다.&lt;/li&gt;&#10;&lt;li&gt;준비 단계는 매 폴링 직전에 실행된다.&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;Node.js&lt;/code&gt;의 내부 동작을 위한 것이라고만 알고 있자.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h3 id="124-폴-단계poll-phase"&gt;1.2.4. 폴 단계(poll phase)&lt;/h3&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;폴 단계에서는 새로운 I/O 이벤트를 가져와서 관련 콜백을 수행한다.&lt;/li&gt;&#10;&lt;li&gt;소켓 연결과 같은 새로운 커넥션을 맺거나 파일 읽기와 같이 데이터 처리를 받아들이게 된다.&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;watch_queue&lt;/code&gt;를 갖고 있다.&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;watch_queue&lt;/code&gt;가 비어 있지 않다면 큐가 비거나 시스템 실행 한도에 다다를 때까지 동기적으로 모든 콜백을 실행한다.&lt;/li&gt;&#10;&lt;li&gt;큐가 비게 되면 &lt;code&gt;Node.js&lt;/code&gt;는 곷바로 다음 단계를 이동하지 않고 &lt;code&gt;check_queue&lt;/code&gt;, &lt;code&gt;pending_queue&lt;/code&gt;, &lt;code&gt;closing_callback_queue&lt;/code&gt;에 남은 작업이 있는지 검사한 다음 작업이 있다면 다음 단계로 이동한다.&lt;/li&gt;&#10;&lt;li&gt;큐가 모두 비어서 해야할 작업이 없다면 잠시 대기를 하게 된다.&#10;&lt;ul&gt;&#10;&lt;li&gt;타이머 최소 힙의 첫 번째 타이머를 꺼내어 지금 실행할 수 있는 상태라면 그 시간만큼 대기한 후 다음 단계로 이동한다.&lt;/li&gt;&#10;&lt;li&gt;바로 타이머 단계로 넘어간다고 해도 어차피 첫 번째 타이머를 수행할 시간이 되지 않았기 때문에 이벤트 루프를 한 번 더 돌아야 하기 때문이다.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h3 id="125-체크-단계check-phase"&gt;1.2.5. 체크 단계(check phase)&lt;/h3&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;code&gt;setImmediate&lt;/code&gt;의 콜백만을 위한 단계&lt;/li&gt;&#10;&lt;li&gt;큐가 비거나 시스템 실행 한도에 도달할 때까지 콜백을 수행&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h3 id="126-종료-콜백-단계close-callback-phase"&gt;1.2.6. 종료 콜백 단계(close callback phase)&lt;/h3&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;&lt;code&gt;socket.on('close', () =&amp;gt; {})&lt;/code&gt;과 같은 close나 destroy 이벤트 타입의 콜백이 처리된다.&lt;/p&gt;</description></item></channel></rss>