9 min read

OSTEP 33 Event-based Concurrency

Table of Contents

node.js๋กœ ๋ฐฑ์—”๋“œ๋ฅผ ๋งŒ๋“ค์–ด ๋ดค์œผ๋ฉด node.js๊ฐ€ ์–ด๋–ป๊ฒŒ ์ž‘๋™ํ•˜๋Š”์ง€ ์•Œ ์ˆ˜ ์žˆ์„ ๊ฒƒ์ด๋‹ค. ์ด๋ฒคํŠธ ๊ธฐ๋ฐ˜์˜ ๋ณ‘ํ–‰์„ฑ์€ ์„œ๋ฒ„ ํ”„๋ ˆ์ž„์›Œํฌ์—์„œ ์‚ฌ์šฉ๋˜์ง€๋งŒ, ๊ทธ ์‹œ์ž‘์ ์€ C์™€ ์œ ๋‹‰์Šค ์‹œ์Šคํ…œ์ด๋‹ค.

์ด๋ฒคํŠธ ๊ธฐ๋ฐ˜์˜ ๋ณ‘ํ–‰์„ฑ์€ ๋‘ ๊ฐœ์˜ ๋ฌธ์ œ์ ์„ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค.

์šฐ์„  ๋ฉ€ํ‹ฐ ์“ฐ๋ ˆ๋“œ ํ”„๋กœ๊ทธ๋žจ์—์„œ ์ด๋ฒคํŠธ ๊ธฐ๋ฐ˜ ๋ณ‘ํ–‰์„ฑ์„ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ๋งค์šฐ ์–ด๋ ต๋‹ค๋Š” ๊ฒƒ์ด๋‹ค. ๋ฝ์„ ๋ˆ„๋ฝ์‹œํ‚ค๊ฑฐ๋‚˜, ๊ต์ฐฉ ์ƒํƒœ ๋˜๋Š” ๋‹ค๋ฅธ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

๋˜, ๋ฉ€ํ‹ฐ ์“ฐ๋ ˆ๋“œ ํ”„๋กœ๊ทธ๋žจ์—์„œ๋Š” ๊ฐœ๋ฐœ์ž๊ฐ€ ์“ฐ๋ ˆ๋“œ ์Šค์ผ€์ค„๋ง์— ๋Œ€ํ•œ ์ œ์–ด๊ถŒ์„ ์ „ํ˜€ ๊ฐ€์ง€๊ณ  ์žˆ์ง€ ์•Š๋‹ค๋Š” ๊ฒƒ์ด๋‹ค. ๊ฐœ๋ฐœ์ž๋Š” ์šด์˜์ฒด์ œ๊ฐ€ ํ•ฉ๋ฆฌ์ ์œผ๋กœ ์Šค์ผ€์ค„๋งํ•ด์ฃผ๊ธฐ๋ฅผ ๊ธฐ๋Œ€ํ•  ์ˆ˜๋ฐ–์— ์—†๋‹ค.

์–ด๋–ป๊ฒŒ ์“ฐ๋ ˆ๋“œ ์—†์ด ๋ณ‘ํ–‰ ์„œ๋ฒ„๋ฅผ ๊ฐœ๋ฐœํ•˜๊ณ , ๊ฐ์ข… ๋ฌธ์ œ๋“ค์„ ํ”ผํ•  ์ˆ˜ ์žˆ์„๊นŒ?

1. ์ด๋ฒคํŠธ ๋ฃจํ”„

์šฐ๋ฆฌ๊ฐ€ ๋‹ค๋ฃฐ ๋ฐฉ๋ฒ•์€ ์ด๋ฒคํŠธ ๊ธฐ๋ฐ˜์˜ ๋ณ‘ํ–‰์„ฑ์ด๋‹ค. ์ ‘๊ทผ ๋ฐฉ๋ฒ•์€ ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

ํŠน์ • ์‚ฌ๊ฑด (์ด๋ฒคํŠธ) ์˜ ๋ฐœ์ƒ์„ ๋Œ€๊ธฐํ•œ๋‹ค. ์‚ฌ๊ฑด์ด ๋ฐœ์ƒํ•˜๋ฉด, ์‚ฌ๊ฑด์˜ ์ข…๋ฅ˜๋ฅผ ํŒŒ์•…ํ•œ ํ›„, I/O๋ฅผ ์š”์ฒญํ•˜๊ฑฐ๋‚˜ ์ถ”ํ›„ ์ฒ˜๋ฆฌ๋ฅผ ์œ„ํ•˜์—ฌ ๋‹ค๋ฅธ ์ด๋ฒคํŠธ๋ฅผ ๋ฐœ์ƒ์‹œํ‚ค๊ฑฐ๋‚˜ ํ•˜๋Š” ๋“ฑ์˜ ์ž‘์—…์„ ํ•œ๋‹ค.

์ž์„ธํ•œ ์„ค๋ช… ์ „์— ๊ณ ์ „์ ์ธ ์ด๋ฒคํŠธ ๊ธฐ๋ฐ˜์˜ ์„œ๋ฒ„๊ฐ€ ์–ด๋–ป๊ฒŒ ์ƒ๊ฒผ๋Š”์ง€ ์‚ดํŽด๋ณด์ž. ์ด ์‘์šฉ ํ”„๋กœ๊ทธ๋žจ์€ ์ด๋ฒคํŠธ ๋ฃจํ”„ (event loop) ๋ผ๋Š” ๋‹จ์ˆœํ•œ ๊ตฌ์กฐ๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ์งœ์—ฌ ์žˆ๋‹ค.

while (1) {
	events = getEvents();
	for (e in events) {
		processEvent(e);
	}
}

๋งค์šฐ ๊ฐ„๋‹จํ•˜๋‹ค. ๋ฃจํ”„ ๋‚ด์—์„œ ์‚ฌ๊ฑด ๋ฐœ์ƒ์„ ๋Œ€๊ธฐํ•œ๋‹ค. ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด ํ•˜๋‚˜์”ฉ ์ฒ˜๋ฆฌํ•œ๋‹ค. ์ด ๋•Œ ๊ฐ ์ด๋ฒคํŠธ๋ฅผ ์ฒ˜๋ฆฌํ•˜๋Š” ์ฝ”๋“œ๋ฅผ ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ (event handler) ๋ผ๊ณ  ๋ถ€๋ฅธ๋‹ค.

์ค‘์š”ํ•œ ๊ฒƒ์€ ์ด๋ฒคํŠธ์˜ ์ฒ˜๋ฆฌ๊ฐ€ ์‹œ์Šคํ…œ์˜ ์œ ์ผํ•œ ์ž‘์—…์ด๊ธฐ ๋•Œ๋ฌธ์—, ๋‹ค์Œ์— ์ฒ˜๋ฆฌํ•  ์ด๋ฒคํŠธ๋ฅผ ๊ฒฐ์ •ํ•˜๋Š” ๊ฒƒ์ด ์Šค์ผ€์ค„๋ง๊ณผ ๋™์ผํ•œ ํšจ๊ณผ๋ฅผ ๊ฐ–๋Š”๋‹ค. ์Šค์ผ€์ค„๋ง์„ ์ œ์–ดํ•  ์ˆ˜ ์žˆ๋Š” ๊ธฐ๋Šฅ์ด ์ด๋ฒคํŠธ ๊ธฐ๋ฐ˜ ๋ฐฉ๋ฒ•์˜ ํฐ ์žฅ์  ์ค‘ ํ•˜๋‚˜์ด๋‹ค.

ํ•˜์ง€๋งŒ ๋ฐœ์ƒํ•œ ์ด๋ฒคํŠธ๊ฐ€ ๋ฌด์Šจ ์ด๋ฒคํŠธ์ธ์ง€ ์–ด๋–ป๊ฒŒ ํŒ๋‹จํ•˜์ง€?

๋„คํŠธ์›Œํฌ๋‚˜ ๋””์Šคํฌ I/O์˜ ๊ฒฝ์šฐ๋Š” ๋” ์–ด๋ ต๋‹ค. ๋””์Šคํฌ I/O๊ฐ€ ์™„๋ฃŒ๋˜์—ˆ๋‹ค๋Š” ์ด๋ฒคํŠธ๊ฐ€ ๋„์ฐฉํ–ˆ์„ ๋•Œ ์–ด๋–ค ๋””์Šคํฌ ์š”์ฒญ์ด ์™„๋ฃŒ๋œ๊ฑธ๊นŒ? ๋„์ฐฉํ•œ ๋ฉ”์‹œ์ง€๊ฐ€ ์ž์‹ ์„ ์œ„ํ•œ ๊ฒƒ์ธ์ง€ ์–ด๋–ป๊ฒŒ ์•Œ ์ˆ˜ ์žˆ์„๊นŒ?

2. ์ค‘์š” API: select() (๋˜๋Š” poll())

์ด๋ฒคํŠธ๋ฅผ ์–ด๋–ป๊ฒŒ ๋ฐ›์„๊นŒ? ๋Œ€๋ถ€๋ถ„์˜ ์‹œ์Šคํ…œ์€ select() ๋˜๋Š” poll() ์‹œ์Šคํ…œ ์ฝœ์„ ๊ธฐ๋ณธ API๋กœ์„œ ์ œ๊ณตํ•œ๋‹ค. ์ธํ„ฐํŽ˜์ด์Šค์˜ ๊ธฐ๋Šฅ์€ ๋„์ฐฉํ•œ I/O๋“ค ์ค‘ ์ฃผ๋ชฉํ•  ๋งŒํ•œ ๊ฒƒ์ด ์žˆ๋Š”์ง€๋ฅผ ๊ฒ€์‚ฌํ•˜๋Š” ๊ฒƒ์ด๋‹ค.

์˜ˆ๋ฅผ ๋“ค์–ด, ์›น ์„œ๋ฒ„๊ฐ™์€ ๋„คํŠธ์›Œํฌ ์‘์šฉ ํ”„๋กœ๊ทธ๋žจ์ด ์ž์‹ ์ด ์ฒ˜๋ฆฌํ•  ํŒจํ‚ท์˜ ๋„์ฐฉ ์—ฌ๋ถ€๋ฅผ ๊ฒ€์‚ฌํ•˜๋Š” ๊ฒƒ์ด๋‹ค. ์ด ์‹œ์Šคํ…œ ์ฝœ๋“ค์ด ์ •ํ™•ํžˆ ํ•ด๋‹น ์—ญํ• ์„ ํ•œ๋‹ค.

select()๋ฅผ ์˜ˆ๋กœ ์‚ดํŽด๋ณด์ž. Mac OS X๊ฐ€ ์ œ๊ณตํ•˜๋Š” ๋ฉ”๋‰ด์–ผ์€ ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

int select(int nfds,
		   fd_set *restrict readfds,
		   fd_set *restrict writefds,
		   fd_set *restrict errorfds,
		   struct timeval *restrict timeout);

select()๋Š” readfds, writefds, errorfds๋ฅผ ํ†ตํ•ด ์ „๋‹ฌ๋œ I/O ๋””์Šคํฌ๋ฆฝํ„ฐ ์ง‘ํ•ฉ๋“ค์„ ๊ฒ€์‚ฌํ•ด์„œ ๊ฐ ๋””์Šคํฌ๋ฆฝํ„ฐ๋“ค์— ํ•ด๋‹นํ•˜๋Š” ์ž…์ถœ๋ ฅ ๋””๋ฐ”์ด์Šค๊ฐ€ ์ฝ์„ ์ค€๋น„๊ฐ€ ๋˜์—ˆ๋Š”์ง€, ์“ธ ์ค€๋น„๊ฐ€ ๋˜์—ˆ๋Š”์ง€, ์ฒ˜๋ฆฌํ•ด์•ผ ํ•  ์˜ˆ์™ธ ์กฐ๊ฑด์ด ๋ฐœ์ƒํ–ˆ๋Š”์ง€ ๋“ฑ์„ ํŒŒ์•…ํ•œ๋‹ค. ๊ฐ ์ง‘ํ•ฉ์˜ ์ฒซ ๋ฒˆ์งธ nfds๊ฐœ์˜ ๋””์Šคํฌ๋ฆฝํ„ฐ๋“ค์„ ๊ฒ€์‚ฌํ•œ๋‹ค. select()๋Š” ์ง‘ํ•ฉ์„ ๊ฐ€๋ฆฌํ‚ค๋Š” ๊ฐ ํฌ์ธํ„ฐ๋“ค์„ ์ค€๋น„๋œ ๋””์Šคํฌ๋ฆฝํ„ฐ๋“ค์˜ ์ง‘ํ•ฉ์œผ๋กœ ๊ต์ฒดํ•œ๋‹ค. select()๋Š” ์ „์ฒด ์ง‘ํ•ฉ์—์„œ ์ค€๋น„๋œ ๋””์Šคํฌ๋ฆฝํ„ฐ๋“ค์˜ ์ด ๊ฐœ์ˆ˜๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

select()์— ๋Œ€ํ•ด ์•Œ์•„๋‘์–ด์•ผ ํ•  ์‚ฌํ•ญ์ด ๋‘ ๊ฐ€์ง€ ์žˆ๋‹ค.

  1. select()๋ฅผ ์ด์š”ํ•˜๋ฉด ๋””์Šคํฌ๋ฆฝํ„ฐ์— ๋Œ€ํ•œ ์ฝ๊ธฐ ๊ฐ€๋Šฅ ์—ฌ๋ถ€, ์“ฐ๊ธฐ ๊ฐ€๋Šฅ ์—ฌ๋ถ€๋ฅผ ๊ฒ€์‚ฌํ•  ์ˆ˜ ์žˆ๋‹ค. ์ „์ž(์ฝ๊ธฐ ๊ฐ€๋Šฅ ์—ฌ๋ถ€)๋Š” ์ฒ˜๋ฆฌํ•ด์•ผ ํ•  ํŒจํ‚ท์˜ ๋„์ฐฉ ์—ฌ๋ถ€๋ฅผ ์•Œ ์ˆ˜ ์žˆ๋„๋ก ํ•œ๋‹ค. ํ›„์ž(์“ฐ๊ธฐ ๊ฐ€๋Šฅ ์—ฌ๋ถ€)๋Š” ์„œ๋น„์Šค๊ฐ€ ์‘๋‹ต ์ „์†ก์ด ๊ฐ€๋Šฅํ•œ ์‹œ์ ์„ ํŒŒ์•…ํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•œ๋‹ค. (์˜ˆ๋ฅผ ๋“ค์–ด, outbound queue๊ฐ€ ๊ฐ€๋“ ์ฐจ์ง€ ์•Š์€ ์ƒํƒœ)

  2. timeout ์กด์žฌ ์ผ๋ฐ˜์ ์œผ๋กœ๋Š” NULL๋กœ ์„ค์ •ํ•˜์—ฌ ๋ฌดํ•œ์ • ๋Œ€๊ธฐํ•˜์ง€๋งŒ ์˜ค๋ฅ˜์— ๋Œ€๋น„ํ•˜๋„๋ก ์„ค๊ณ„๋œ ์„œ๋ฒ„๋Š” ๊ฐ’์„ ์„ค์ •ํ•˜๊ธฐ๋„ ํ•œ๋‹ค. ๋„๋ฆฌ ์‚ฌ์šฉ๋˜๋Š” ๋ฐฉ๋ฒ•์œผ๋กœ๋Š”, timeout = 0์œผ๋กœ ์„ค์ •ํ•˜์—ฌ select()๊ฐ€ ๋Œ€๊ธฐํ•˜์ง€ ์•Š๊ณ  ์ฆ‰์‹œ ๋ฆฌํ„ดํ•˜๋„๋ก ํ•˜๋Š” ๊ฒƒ์ด๋‹ค.

poll() ์‹œ์Šคํ…œ ์ฝœ๋„ ์œ ์‚ฌํ•˜๊ฒŒ ์ž‘๋™ํ•œ๋‹ค.

์ด๋Ÿฐ ๊ธฐ๋ณธ ํ•จ์ˆ˜๋กœ non blocking event loop๋ฅผ ๋งŒ๋“ค์–ด, ํŒจํ‚ท ๋„์ฐฉ์„ ํ™•์ธํ•˜๊ณ , ์†Œ์ผ“์—์„œ ๋ฉ”์‹œ์ง€๋ฅผ ์ฝ๊ณ  ํ•„์š”์— ์‘๋‹ตํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ด์ค€๋‹ค.

3. select()์˜ ์‚ฌ์šฉ

ํ™•์‹คํ•œ ์ดํ•ด๋ฅผ ์œ„ํ•ด, ์–ด๋–ค ๋„คํŠธ์›Œํฌ ๋””์Šคํฌ๋ฆฝํ„ฐ์— ๋ฉ”์‹œ์ง€๊ฐ€ ๋„์ฐฉํ–ˆ๋Š”์ง€๋ฅผ ํŒŒ์•…ํ•˜๋Š” ๊ฒฝ์šฐ๋ฅผ ์‚ดํŽด๋ณด์ž.

#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>

int main(void) {
	// ์—ฌ๋Ÿฌ ๊ฐœ์˜ ์†Œ์ผ“์„ ์—ด๊ณ  ์„ค์ • (์—ฌ๊ธฐ์—๋Š” ์•ˆ์จ์žˆ์Œ)
	// ์ฃผ ๋ฐ˜๋ณต๋ฌธ
	while () {
		// fd_set์„ ๋ชจ๋‘ 0์œผ๋กœ ์ดˆ๊ธฐํ™”
		fd_set readFDs;
		FD_ZERO(&readFDs);

		// ์ด์ œ ์ด ์„œ๋ฒ„๊ฐ€ ๊ด€์‹ฌ์„ ๊ฐ€์ง€๋Š” ๋””์Šคํฌ๋ฆฝํ„ฐ๋“ค์˜ bit ์„ค์ •
		// (min ~ max)
		int fd;
		for (fd = minFD; fd < maxFD; fd++)
			FD_SET(fd, &readFDs);

		// select
		int rc = select(maxFD, &readFDs, NULL, NULL, NULL);
		
		// FD_ISSET()์„ ์‚ฌ์šฉํ•˜์—ฌ ์‹ค์ œ ๋ฐ์ดํ„ฐ ์‚ฌ์šฉ ์—ฌ๋ถ€ ๊ฒ€์‚ฌ
		int fd;
		for (fd = minFD; fd < maxFD; fd++)
		if (FD_ISSET(fd, &readFDs))
		processFD(fd);
	}
}

๋งจ ์ฒ˜์Œ ์ดˆ๊ธฐํ™” ํ›„, ์„œ๋ฒ„๋Š” ๋ฌดํ•œ ๋ฃจํ”„์— ๋“ค์–ด๊ฐ„๋‹ค. ๊ทธ ๋ฃจํ”„ ๋‚ด์—์„œ FD_ZERO() ๋งคํฌ๋กœ๋ฅผ ํ†ตํ•ด ํŒŒ์ผ ๋””์Šคํฌ๋ฆฝํ„ฐ๋“ค์„ ์ดˆ๊ธฐํ™”ํ•œ ํ›„, FD_SET()์„ ์‚ฌ์šฉํ•˜์—ฌ minFD ~ maxFD๊นŒ์ง€์˜ ํŒŒ์ผ ๋””์Šคํฌ๋ฆฝํ„ฐ ์ง‘ํ•ฉ์— ํฌํ•จ์‹œํ‚จ๋‹ค. ์ด ์ง‘ํ•ฉ์€ ์„œ๋ฒ„๊ฐ€ ๋ณด๊ณ  ์žˆ๋Š” ๋ชจ๋“  ๋„คํŠธ์›Œํฌ ์†Œ์ผ“๊ฐ™์€ ๊ฒƒ๋“ค์„ ๋‚˜ํƒ€๋‚ผ ์ˆ˜ ์žˆ๋‹ค.

๋งˆ์ง€๋ง‰์œผ๋กœ ์„œ๋ฒ„๋Š” select()๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ๋ฐ์ดํ„ฐ๊ฐ€ ๋„์ฐฉํ•œ ์†Œ์ผ“์ด ์žˆ๋Š”์ง€๋ฅผ ๊ฒ€์‚ฌํ•œ๋‹ค. ๋ฐ˜๋ณต๋ฌธ ๋‚ด์˜ FD_ISSET()์„ ์‚ฌ์šฉํ•˜์—ฌ ์ด๋ฒคํŠธ ์„œ๋ฒ„๋Š” ์–ด๋–ค ๋””์Šคํฌ๋ฆฝํ„ฐ๋“ค์ด ์ค€๋น„๋œ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๋Š”์ง€๋ฅผ ์•Œ ์ˆ˜ ์žˆ๊ณ , ๋„์ฐฉํ•˜๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋œ๋‹ค.

์‹ค์ œ ์„œ๋ฒ„๋Š” ๋””์Šคํฌ ์ž‘์—…, ๋ฉ”์‹œ์ง€๋ฅผ ๋ณด๋‚ด๋Š” ์‹œ์ , ๋“ฑ ์„ธ๋ถ€ ์‚ฌํ•ญ๋“ค์„ ๊ฒฐ์ •ํ•˜๋Š” ๋กœ์ง์ด ํ•„์š”ํ•˜๋‹ค.

ํŒ: ์ด๋ฒคํŠธ ๊ธฐ๋ฐ˜์˜ ์„œ๋ฒ„ ๋‚ด์—์„œ๋Š” ๋ธ”๋Ÿญ์„ ํ•˜์ง€ ๋ง์ž. ์ด๋ฒคํŠธ ๊ธฐ๋ฐ˜ ์„œ๋ฒ„๋Š” ์ž‘์—…์˜ ์Šค์ผ€์ค„๋ง์„ ์ •๋ฐ€ํ•˜๊ฒŒ ์ œ์–ดํ•  ์ˆ˜ ์žˆ๋‹ค. ํ•˜์ง€๋งŒ, ์ •๋ฐ€ํ•œ ์ œ์–ด๋ฅผ ์œ„ํ•ด์„œ๋Š” ํ˜ธ์ถœ์ž๊ฐ€ ์‹คํ–‰ํ•œ ๊ฒƒ์„ ์ฐจ๋‹จํ•  ์ˆ˜ ์žˆ๋Š” ์–ด๋– ํ•œ ํ˜ธ์ถœ๋„ ์žˆ์–ด์„œ๋Š” ์•ˆ ๋œ๋‹ค. ์ด ๋””์ž์ธ ํŒ์„ ์ง€ํ‚ค์ง€ ์•Š๋Š”๋‹ค๋ฉด ์ด๋ฒคํŠธ ๊ธฐ๋ฐ˜ ์„œ๋ฒ„๊ฐ€ ๋ฉˆ์ถ”๊ฒŒ ๋  ๊ฒƒ์ด๊ณ  ์‚ฌ์šฉ์ž๋Š” ๋ถˆ๋งŒ์„ ๊ฐ€์งˆ ๊ฒƒ์ด๋‹ค.

4. ์™œ ๊ฐ„๋‹จํ•œ๊ฐ€? -> ๋ฝ์ด ํ•„์š” ์—†์Œ

๋‹จ์ผ CPU๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์ด๋ฒคํŠธ ๊ธฐ๋ฐ˜์˜ ์‘์šฉ ํ”„๋กœ๊ทธ๋žจ์—์„œ๋Š”, ๋ณ‘ํ–‰ ํ”„๋กœ๊ทธ๋žจ์„ ๋‹ค๋ฃฐ ๋•Œ ๋‚˜ํƒ€๋‚ฌ๋˜ ๋ฌธ์ œ๋“ค์ด ๋” ์ด์ƒ ๋ณด์ด์ง€ ์•Š๋Š”๋‹ค.

๊ทธ ์ด์œ ๋Š” ๋งค ์ˆœ๊ฐ„์— ๋‹จ ํ•˜๋‚˜์˜ ์ด๋ฒคํŠธ๋งŒ ๋‹ค๋ฃจ๊ธฐ ๋•Œ๋ฌธ์— ๋ฝ์„ ํš๋“ํ•˜๊ฑฐ๋‚˜ ํ•ด์ œํ•  ํ•„์š”๊ฐ€ ์—†๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. ์ด๋ฒคํŠธ ๊ธฐ๋ฐ˜์˜ ์„œ๋ฒ„๋Š” ๋‹จ ํ•˜๋‚˜์˜ ์“ฐ๋ ˆ๋“œ๋งŒ ๊ฐ€์ง€๊ณ  ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ๋‹ค๋ฅธ ์“ฐ๋ ˆ๋“œ์— ์˜ํ•ด ์ธํ„ฐ๋ŸฝํŠธ์— ๊ฑธ๋ฆด ์ˆ˜๊ฐ€ ์—†๋‹ค. ๊ทธ๋ ‡๊ธฐ ๋•Œ๋ฌธ์— ๋ฉ€ํ‹ฐ์“ฐ๋ ˆ๋“œ ํ”„๋กœ๊ทธ๋žจ์˜ ๋ณ‘ํ–‰์„ฑ ๋ฒ„๊ทธ๋Š” ๊ธฐ๋ณธ์ ์ธ ์ด๋ฒคํŠธ ๊ธฐ๋ฐ˜ ์ ‘๊ทผ๋ฒ•์—์„œ๋Š” ๋‚˜ํƒ€๋‚˜์ง€ ์•Š๋Š”๋‹ค.

5. ๋ฌธ์ œ: ๋ธ”๋กœํ‚น ์‹œ์Šคํ…œ ์ฝœ (Blocking System Call)

๋ธ”๋กœํ‚น์„ ์œ ๋ฐœํ•˜๋Š” ์‹œ์Šคํ…œ ์ฝœ์ด ํ˜ธ์ถœ๋˜๋Š” ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด ์–ด๋–กํ•˜์ง€?

์˜ˆ๋ฅผ ๋“ค์–ด, ๋””์Šคํฌ์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ์ฝ์–ด์„œ ๊ทธ ๋‚ด์šฉ์„ ์‚ฌ์šฉ์ž์—๊ฒŒ ์ „๋‹ฌํ•˜๋Š” ์š”์ฒญ์„ ์ƒ๊ฐํ•ด ๋ณด์ž. ์ด ์š”์ฒญ์„ ์ฒ˜๋ฆฌํ•˜๋ ค๋ฉด ํ•ธ๋“ค๋Ÿฌ๊ฐ€ open() ์‹œ์Šคํ…œ ์ฝœ์„ ํ˜ธ์ถœํ•˜์—ฌ ํŒŒ์ผ์„ ์—ด๊ณ , read()๋กœ ํŒŒ์ผ์„ ์ฝ์–ด์•ผ ํ•œ๋‹ค. ํŒŒ์ผ์„ ์ฝ์–ด์„œ ๋ฉ”๋ชจ๋ฆฌ์— ํƒ‘์žฌํ•œ ํ›„์— ์„œ๋ฒ„๋Š” ๊ทธ ๊ฒฐ๊ณผ๋ฅผ ์‚ฌ์šฉ์ž์—๊ฒŒ ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋œ๋‹ค.

open(), read() ๋‘˜ ๋‹ค ์ €์žฅ ์žฅ์น˜์— I/O ์š”์ฒญ์„ ๋ณด๋‚ด์•ผ ํ•œ๋‹ค๋ฉด, ์ด ์š”์ฒญ์„ ์ฒ˜๋ฆฌํ•˜๊ธฐ ์œ„ํ•ด ์˜ค๋žœ ์‹œ๊ฐ„ใ„ด์ด ํ•„์š”ํ•˜๋‹ค. ์“ฐ๋ ˆ๋“œ ๊ธฐ๋ฐ˜ ์„œ๋ฒ„๋Š” ์ด๋Ÿฐ ๊ฒƒ์ด ๋ฌธ์ œ๊ฐ€ ๋˜์ง€ ์•Š๋Š”๋‹ค. ํ•œ ์“ฐ๋ ˆ๋“œ๊ฐ€ I/O ๋Œ€๊ธฐ๋ฅผ ํ•˜๋Š” ๋™์•ˆ, ๋‹ค๋ฅธ ์“ฐ๋ ˆ๋“œ๊ฐ€ ์‹คํ–‰์ด ๋˜๋ฉฐ ์„œ๋ฒ„๋Š” ๊ณ„์† ๋™์ž‘ํ•  ์ˆ˜ ์žˆ๋‹ค. I/O ์ฒ˜๋ฆฌ์™€ ๋‹ค๋ฅธ ์—ฐ์‚ฐ์ด ์ž์—ฐ์Šค๋Ÿฝ๊ฒŒ ๊ฒน์ณ์ง€๋Š” ํ˜„์ƒ์ด ์“ฐ๋ ˆ๋“œ ๊ธฐ๋ฐ˜ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์˜ ์žฅ์ ์ด๋‹ค.

๋ฐ˜๋ฉด ์ด๋ฒคํŠธ ๊ธฐ๋ฐ˜ ์ ‘๊ทผ๋ฒ•์—์„œ๋Š” ์“ฐ๋ ˆ๋“œ๊ฐ€ ์—†๊ณ  ์ด๋ฒคํŠธ ๋ฃจํ”„๋งŒ ์กด์žฌํ•œ๋‹ค. ์ฆ‰, ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ๊ฐ€ ๋ธ”๋กœํ‚น ์‹œ์Šคํ…œ ์ฝœ์„ ํ˜ธ์ถœํ•˜๋ฉด ์„œ๋ฒ„ ์ „์ฒด๊ฐ€ ์˜ค์ง ๊ทธ ์ผ์„ ์ฒ˜๋ฆฌํ•˜๊ธฐ ์œ„ํ•ด ๋ช…๋ น์–ด๊ฐ€ ๋๋‚  ๋•Œ๊นŒ์ง€ ๋ชจ๋“  ๊ฒƒ์„ ์ฐจ๋‹จํ•œ๋‹ค. ์ด๋ฒคํŠธ ๊ธฐ๋ฐ˜ ์‹œ์Šคํ…œ์˜ ๊ธฐ๋ณธ ์›์น™์€ ๋ธ”๋กœํ‚น ํ˜ธ์ถœ์„ ํ—ˆ์šฉํ•˜๋ฉด ์•ˆ ๋œ๋‹ค๋Š” ๊ฒƒ์ด๋‹ค.

6. ํ•ด๋ฒ•: ๋น„๋™๊ธฐ I/O

์—ฌ๋Ÿฌ ํ˜„๋Œ€์˜ ์šด์˜์ฒด์ œ๋“ค์ด I/O ์š”์ฒญ์„ ๋””์Šคํฌ๋กœ ๋‚ด๋ ค ๋ณด๋‚ผ ์ˆ˜ ์žˆ๋Š”, ์ผ๋ฐ˜์ ์œผ๋กœ ๋น„๋™๊ธฐ I/O (asynchronous I/O) ๋ผ๊ณ  ๋ถ€๋ฅด๋Š” ์ƒˆ๋กœ์šด ๋ฐฉ๋ฒ•์„ ๊ฐœ๋ฐœํ•˜์˜€๋‹ค.

์ด ์ธํ„ฐํŽ˜์ด์Šค๋Š” ํ”„๋กœ๊ทธ๋žจ์ด I/O ์š”์ฒญ์„ ํ•˜๋ฉด, I/O ์š”์ฒญ์ด ๋๋‚˜๊ธฐ ์ „์— ์ œ์–ด๊ถŒ์„ ์ฆ‰์‹œ ๋‹ค์‹œ ํ˜ธ์ถœ์ž์—๊ฒŒ ๋Œ๋ ค์ฃผ๋Š” ๊ฒƒ์„ ๊ฐ€๋Šฅํ•˜๊ฒŒ ํ–ˆ์œผ๋ฉฐ, ์ถ”๊ฐ€์ ์œผ๋กœ ์—ฌ๋Ÿฌ ์ข…๋ฅ˜์˜ I/O๋“ค์ด ์™„๋ฃŒ๋˜์—ˆ๋Š”์ง€ ํŒ๋‹จํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•˜์˜€๋‹ค.

Mac OS X๊ฐ€ ์ œ๊ณตํ•˜๋Š” ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์‚ดํŽด๋ณด์ž.

struct aiocb {
	int            aio_fildes; /* File descriptor */
	off_t          aio_offset; /* File offset */
	volatile void    *aio_buf; /* Location of buffer */
	size_t         aio_nbytes; /* Length of transfer */
};

์ด API๋Š” struct aiocb, AIO ์ œ์–ด ๋ธ”๋Ÿญ(AIO Control block) ์ด๋ผ๊ณ  ๋ถˆ๋ฆฌ๋Š” ๊ตฌ์กฐ๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๋‹ค.

ํŒŒ์ผ์— ๋Œ€ํ•œ ๋น„๋™๊ธฐ ์ฝ๊ธฐ ์š”์ฒญ์„ ํ•˜๋ ค๋ฉด, ์‘์šฉ ํ”„๋กœ๊ทธ๋žจ์€ ๋จผ์ € ์ด ์ž๋ฃŒ ๊ตฌ์กฐ์— ์ฝ๊ณ ์ž ํ•˜๋Š” ํŒŒ์ผ ๋””์Šคํฌ๋ฆฝํ„ฐ (aio_fildes), ํŒŒ์ผ ๋‚ด์—์„œ์˜ ์œ„์น˜ (aio_offset), ์š”์ฒญ์˜ ๊ธธ์ด (aio_nbytes), ์ฝ๊ธฐ ๊ฒฐ๊ณผ๋กœ ์–ป๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ•  ๋ฉ”๋ชจ๋ฆฌ์˜ ์œ„์น˜ (aio_buf)์™€ ๊ฐ™์€ ์ •๋ณด๊ฐ€ ํ•„์š”ํ•˜๋‹ค.

Mac OS X์—์„œ๋Š” ๊ฐ„๋‹จํ•œ ๋น„๋™๊ธฐ ์ฝ๊ธฐ (asynchronous read) API๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.

int aio_read(struct aiocb *aiocbp);

์ด ๋ช…๋ น์–ด๋ฅผ ํ†ตํ•ด I/O ํ˜ธ์ถœ์„ ์„ฑ๊ณตํ•˜๋ฉด, ์ฆ‰์‹œ ๋ฆฌํ„ด์„ ํ•˜๋ฉฐ ์‘์šฉ ํ”„๋กœ๊ทธ๋žจ (์ด๋ฒคํŠธ ๊ธฐ๋ฐ˜์˜ ์„œ๋ฒ„ ๋“ฑ) ์€ ํ•˜๋˜ ์ผ์„ ๊ณ„์† ์ง„ํ–‰ํ•  ์ˆ˜ ์žˆ๋‹ค.

๊ทธ๋Ÿฌ๋ฉด I/O๊ฐ€ ์ข…๋ฃŒ๋˜์—ˆ๋‹ค๋Š” ๊ฒƒ์„ ์–ด๋–ป๊ฒŒ ์•Œ ์ˆ˜ ์žˆ์„๊นŒ?, ๊ทธ๋ฆฌ๊ณ  aio_buf๊ฐ€ ๊ฐ€๋ฆฌํ‚ค๋Š” ๋ฒ„ํผ์— ์š”์ฒญํ–ˆ๋˜ ๋ฐ์ดํ„ฐ๊ฐ€ ์žˆ๋‹ค๋Š” ๊ฒƒ์„ ์–ด๋–ป๊ฒŒ ์•Œ ์ˆ˜ ์žˆ์„๊นŒ?

API๊ฐ€ ํ•˜๋‚˜๊ฐ€ ํ•„์š”ํ•˜๋‹ค. Mac OS X ์—์„œ๋Š” ์ด API๋ฅผ aio_error()๋ผ๊ณ  ํ•œ๋‹ค.

int aio_error(const struct aiocb *aiocbp);

์ด ์‹œ์Šคํ…œ ์ฝœ์€ aiocbp์— ์˜ํ•ด ์ฐธ์กฐ๋œ ์š”์ฒญ์ด ์™„๋ฃŒ๋˜์—ˆ๋Š”์ง€๋ฅผ ๊ฒ€์‚ฌํ•œ๋‹ค. ์™„๋ฃŒ๋˜์—ˆ๋‹ค๋ฉด ์„ฑ๊ณตํ–ˆ๋‹ค๊ณ  ๋ฆฌํ„ด์„ ํ•˜๊ณ  (0์œผ๋กœ ํ‘œ์‹œ) ์‹คํŒจํ–ˆ๋‹ค๋ฉด EINPROGRESS๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค. ๋ชจ๋“  ๋Œ€๊ธฐ ์ค‘์ธ ๋น„๋™๊ธฐ I/O๋Š” ์ฃผ๊ธฐ์ ์œผ๋กœ aio_error() ์‹œ์Šคํ…œ ์ฝœ๋กœ ์‹œ์Šคํ…œ์— ํด๋ง(polling)ํ•˜์—ฌ ํ•ด๋‹น I/O๊ฐ€ ์™„๋ฃŒ๋˜์—ˆ๋Š”์ง€ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

์–ด๋–ค I/O๊ฐ€ ์™„๋ฃŒ๋˜์—ˆ๋Š”์ง€ ํ™•์ธํ•˜๋Š” ๊ฒƒ์ด ๊ท€์ฐฎ์„ ์ˆ˜๋„ ์žˆ๋‹ค. ๋™์‹œ์— ์ˆ˜๋ฐฑ๊ฐœ์˜ I/O๋ฅผ ์š”์ฒญํ•˜๋Š” ํ”„๋กœ๊ทธ๋žจ์˜ ๊ฒฝ์šฐ, ์ด ๋ชจ๋“  ์š”์ฒญ์„ ๋‹ค ํด๋งํ•˜๋ฉด์„œ ๊ฒ€์‚ฌํ•ด์•ผ ํ• ๊นŒ? ์•„๋‹ˆ๋ฉด ์ผ์ • ์‹œ๊ฐ„ ๊ธฐ๋‹ค๋ ค์•ผ ํ• ๊นŒ?

์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด ์ธํ„ฐ๋ŸฝํŠธ ๊ธฐ๋ฐ˜์˜ ์ ‘๊ทผ๋ฒ•์„ ์ œ๊ณตํ•˜๋Š” ์‹œ์Šคํ…œ๋“ค์ด ์žˆ๋‹ค. ์œ ๋‹‰์Šค์˜ ์‹œ๊ทธ๋„ (signal) ์„ ์‚ฌ์šฉํ•˜์—ฌ ๋น„๋™๊ธฐ I/O๊ฐ€ ์™„๋ฃŒ๋˜์—ˆ๋‹ค๋Š” ๊ฒƒ์„ ์‘์šฉ ํ”„๋กœ๊ทธ๋žจ์—๊ฒŒ ์•Œ๋ ค์ฃผ๊ธฐ ๋•Œ๋ฌธ์— ๋ฐ˜๋ณต์ ์œผ๋กœ ์™„๋ฃŒ ์—ฌ๋ถ€๋ฅผ ํ™•์ธํ•  ํ•„์š”๊ฐ€ ์—†๋‹ค. ํด๋ง ๋Œ€ ์ธํ„ฐ๋ŸฝํŠธ ๋ฌธ์ œ๋Š” I/O ์žฅ์น˜๋“ค์„ ๋‹ค๋ฃฐ ๋•Œ์—๋„ ๋‚˜ํƒ€๋‚œ๋‹ค.

๋น„๋™๊ธฐ I/O๊ฐ€ ์—†๋Š” ์‹œ์Šคํ…œ์—์„œ๋Š” ์ œ๋Œ€๋กœ ๋œ ์ด๋ฒคํŠธ ๊ธฐ๋ฐ˜ ์ ‘๊ทผ๋ฒ•์„ ๊ตฌํ˜„ํ•  ์ˆ˜ ์—†๋‹ค. ๋Œ€์‹  ๋„คํŠธ์›Œํฌ ํŒจํ‚ท์„ ์ฒ˜๋ฆฌํ•˜๊ธฐ ์œ„ํ•ด ์ด๋ฒคํŠธ๋ฅผ ์‚ฌ์šฉํ•˜๊ณ , ๋Œ€๊ธฐ ์ค‘์ธ I/O๋“ค์„ ์ฒ˜๋ฆฌํ•˜๊ธฐ ์œ„ํ•ด ์“ฐ๋ ˆ๋“œ ํ’€์„ ์‚ฌ์šฉํ•˜๋Š” ๋“ฑ์˜ ํ•˜์ด๋ธŒ๋ฆฌ๋“œ ๊ธฐ๋ฒ•์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

7. ๋˜ ๋‹ค๋ฅธ ๋ฌธ์ œ์ : ์ƒํƒœ ๊ด€๋ฆฌ

์ด๋ฒคํŠธ ๊ธฐ๋ฐ˜ ์ ‘๊ทผ๋ฒ•์˜ ๋˜ ๋‹ค๋ฅธ ๋ฌธ์ œ์ ์€ ์ „ํ†ต์ ์ธ ์“ฐ๋ ˆ๋“œ ๊ธฐ๋ฐ˜ ์ฝ”๋“œ๋ณด๋‹ค ์ผ๋ฐ˜์ ์œผ๋กœ ๋” ์ž‘์„ฑํ•˜๊ธฐ ๋ณต์žกํ•˜๋‹ค๋Š” ๊ฒƒ์ด๋‹ค. ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ๊ฐ€ ๋น„๋™๊ธฐ I/O๋ฅผ ๋ฐœ์ƒ์‹œํ‚ฌ ๋•Œ, I/O ์™„๋ฃŒ ์‹œ ์‚ฌ์šฉํ•  ํ”„๋กœ๊ทธ๋žจ ์ƒํƒœ๋ฅผ ์ •๋ฆฌํ•ด ๋†“์•„์•ผ ํ•œ๋‹ค. ์ด ์ž‘์—…์€ ์“ฐ๋ ˆ๋“œ ๊ธฐ๋ฐ˜ ํ”„๋กœ๊ทธ๋žจ์—์„œ๋Š” ๋ถˆํ•„์š”ํ•˜๋‹ค. ์“ฐ๋ ˆ๋“œ ์Šคํƒ์— ๊ทธ ์ •๋ณด๋“ค์ด ์ด๋ฏธ ๋“ค์–ด ์žˆ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. ์ด๋ฒคํŠธ ๊ธฐ๋ฐ˜ ์ ‘๊ทผ๋ฒ•์—์„œ๋Š” ์ˆ˜๋™ ์Šคํƒ ๊ด€๋ฆฌ (manual stack management) ๊ฐ€ ํ•„์š”ํ•˜๋‹ค.

์“ฐ๋ ˆ๋“œ ๊ธฐ๋ฐ˜ ์„œ๋ฒ„๋ฅผ ์˜ˆ๋กœ ๋“ค๋ฉด, ์ด ์„œ๋ฒ„๋Š” ํŒŒ์ผ ๋””์Šคํฌ๋ฆฝํ„ฐ (fd) ๋กœ ๋ช…์‹œ๋œ ํŒŒ์ผ์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ์ฝ์–ด๋“ค์—ฌ, ํ•ด๋‹น ๋ฐ์ดํ„ฐ๋“ค์„ ๋„คํŠธ์›Œํฌ ์†Œ์ผ“ ๋””์Šคํฌ๋ฆฝํ„ฐ (sd)๋กœ ์ „์†กํ•œ๋‹ค.

int rc = read(fd, buffer, size);
rc = write(sd, buffer, size);

๋ฉ€ํ‹ฐ ์“ฐ๋ ˆ๋“œ ํ”„๋กœ๊ทธ๋žจ์—์„œ๋Š”, read()๊ฐ€ ๋ฆฌํ„ด๋˜๋ฉด ์ „์†กํ•  ๋„คํŠธ์›Œํฌ ์†Œ์ผ“์— ๊ด€ํ•œ ์ •๋ณด๊ฐ€ ๊ฐ™์€ ์Šคํƒ์— ์กด์žฌํ•œ๋‹ค. ํ•˜์ง€๋งŒ ์ด๋ฒคํŠธ ๊ธฐ๋ฐ˜์˜ ์‹œ์Šคํ…œ์—์„œ๋Š” ๊ทธ๋ ‡์ง€ ์•Š๋‹ค.

์ด๋ฒคํŠธ ๊ธฐ๋ฐ˜์˜ ์‹œ์Šคํ…œ์—์„œ ๊ฐ™์€ ์ผ์„ ํ•˜๋ ค๋ฉด, ์•ž์„œ ๋ช…์‹œํ•œ AIO ํ˜ธ์ถœ๋“ค์„ ์‚ฌ์šฉํ•˜์—ฌ read()๋ฅผ ๋น„๋™๊ธฐ๋กœ ์š”์ฒญํ•ด์•ผ ํ•œ๋‹ค. aio_error()๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ฃผ๊ธฐ์ ์œผ๋กœ ์ฝ๊ธฐ๊ฐ€ ์ข…๋ฃŒ๋˜์—ˆ๋Š”์ง€ ํ™•์ธํ•œ๋‹ค๊ณ  ๊ฐ€์ •ํ•ด๋ณด์ž. ์ฝ๊ธฐ๊ฐ€ ์ข…๋ฃŒ๋˜์—ˆ๋‹ค๊ณ  ์•Œ๋ ค์ฃผ๋ฉด ์ด๋ฒคํŠธ ๊ธฐ๋ฐ˜ ์„œ๋ฒ„๋Š” ๋‹ค์Œ์œผ๋กœ ๋ฌด์Šจ ์ผ์„ ํ•ด์•ผ ํ•˜๋Š”์ง€ ์–ด๋–ป๊ฒŒ ์•Œ ์ˆ˜ ์žˆ์„๊นŒ?

๊ทธ ํ•ด๋ฒ•์€ continuation์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด๋‹ค.

์ด๋ฒคํŠธ๋ฅผ ์ข…๋ฃŒํ•˜๋Š” ๋ฐ์— ํ•„์š”ํ•œ ์ž๋ฃŒ๋“ค์„ ํ•œ๊ณณ์— ์ €์žฅํ•ด ๋‘”๋‹ค. ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด (๋””์Šคํฌ I/O๊ฐ€ ์™„๋ฃŒ๋˜๋ฉด), ์ €์žฅํ•ด ๋†“์€ ์ •๋ณด๋“ค์„ ํ™œ์šฉํ•˜์—ฌ ์ด๋ฒคํŠธ๋ฅผ ์ฒ˜๋ฆฌํ•œ๋‹ค.

์•ž์„œ ์‚ฌ์šฉํ•œ ์˜ˆ์‹œ์˜ ํ•ด๋ฒ•์€ ์†Œ์ผ“ ๋””์Šคํฌ๋ฆฝํ„ฐ (sd)๋ฅผ ํŒŒ์ผ ๋””์Šคํฌ๋ฆฝํ„ฐ (fd)๊ฐ€ ์‚ฌ์šฉํ•˜๋Š” ์ž๋ฃŒ ๊ตฌ์กฐ (์˜ˆ: ํ•ด์‹œ ํ…Œ์ด๋ธ”)์— ์ €์žฅํ•ด ๋†“๋Š” ๊ฒƒ์ด๋‹ค. ๋””์Šคํฌ I/O๊ฐ€ ์™„๋ฃŒ๋˜๋ฉด ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ๊ฐ€ ํŒŒ์ผ ๋””์Šคํฌ๋ฆฝํ„ฐ์—์„œ ๋‹ค์Œ ํ•  ์ผ์„ ํŒŒ์•…ํ•˜์—ฌ ํ˜ธ์ถœ์ž์—๊ฒŒ ์†Œ์ผ“ ๋””์Šคํฌ๋ฆฝํ„ฐ์˜ ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•˜๋„๋ก ํ•œ๋‹ค. ์ด ์‹œ์ ์—์„œ ์„œ๋ฒ„๋Š” ์†Œ์ผ“์— ๋ฐ์ดํ„ฐ๋ฅผ ๊ธฐ๋กํ•˜๋Š” ๋งˆ์ง€๋ง‰ ๋™์ž‘์„ ํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋œ๋‹ค.

8. ์ด๋ฒคํŠธ ์‚ฌ์šฉ์˜ ์–ด๋ ค์›€

์ด๋ฒคํŠธ ๊ธฐ๋ฐ˜ ์ ‘๊ทผ๋ฒ•์—์„œ๋Š” ๋‹ค๋ฅธ ์–ด๋ ค์šด ์ ์ด ๋ช‡ ๊ฐ€์ง€ ์กด์žฌํ•œ๋‹ค.

๋‹จ์ผ CPU์—์„œ ๋ฉ€ํ‹ฐ CPU๋กœ ๋ณ€๊ฒฝ๋˜๋ฉด, ์ด๋ฒคํŠธ ๊ธฐ๋ฐ˜ ์ ‘๊ทผ๋ฒ•์˜ ๋‹จ์ˆœํ•จ์ด ์—†์–ด์ง„๋‹ค. ํ•˜๋‚˜ ์ด์ƒ์˜ CPU๋ฅผ ํ™œ์šฉํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š”, ๋‹ค์ˆ˜์˜ ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ๋ฅผ ๋ณ‘๋ ฌ์ ์œผ๋กœ ์‹คํ–‰ํ•ด์•ผ ํ•œ๋‹ค. ๊ทธ๋ ‡๊ฒŒ ๋˜๋ฉด ๋™๊ธฐํ™” ๋ฌธ์ œ (์ž„๊ณ„ ์˜์—ญ ๋“ฑ) ์ด ๋ฐœ์ƒํ•˜๊ฒŒ ๋˜๋ฉฐ, ์ด๊ฒƒ์„ ํ•ด๊ฒฐํ•˜๋Š”๋ฐ ํ•„์š”ํ•œ ๋ฝ ๋“ฑ์„ ์‚ฌ์šฉํ•  ์ˆ˜๋ฐ–์— ์—†๋‹ค. ๋•Œ๋ฌธ์— ์ตœ๊ทผ์˜ ๋ฉ€ํ‹ฐ์ฝ”์–ด ์‹œ์Šคํ…œ์€ ๋ฝ์ด ์—†๋Š” ์ด๋ฒคํŠธ ์ฒ˜๋ฆฌ ๋ฐฉ์‹์„ ๋” ์ด์ƒ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†๊ฒŒ ๋œ๋‹ค.

๋˜ ๋‹ค๋ฅธ ๋ฌธ์ œ๋Š”, ํŽ˜์ด์ง• (paging) ๊ณผ ๊ฐ™์€ ํŠน์ • ์ข…๋ฅ˜์˜ ์‹œ์Šคํ…œ๊ณผ ์ž˜ ๋งž์ง€ ์•Š๋Š”๋‹ค. ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ์—์„œ ํŽ˜์ด์ง€ ํดํŠธ๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด ๋™์ž‘์ด ์ค‘๋‹จ๋˜๊ธฐ ๋•Œ๋ฌธ์— ์„œ๋ฒ„๋Š” ํŽ˜์ด์ง€ ํดํŠธ๊ฐ€ ์ฒ˜๋ฆฌ ์™„๋ฃŒ๋˜๊ธฐ ์ „๊นŒ์ง€๋Š” ์ง„ํ–‰์„ ํ•  ์ˆ˜ ์—†๋‹ค. ์„œ๋ฒ„๊ฐ€ ๋…ผ๋ธ”๋กœํ‚น ๋ฐฉ์‹์œผ๋กœ ์„ค๊ณ„๋˜์—ˆ๋‹ค ํ•ด๋„, ํŽ˜์ด์ง€ ํดํŠธ๋กœ ์ธํ•œ ๋ธ”๋กœํ‚น์€ ํ”ผํ•˜๊ธฐ ์–ด๋ ต๋‹ค. ์ด๋Ÿฐ ์ƒํ™ฉ์ด ์ž์ฃผ ๋ฐœ์ƒํ•˜๋ฉด ์‹ฌ๊ฐํ•œ ์„ฑ๋Šฅ ์ €ํ•˜๊ฐ€ ์ผ์–ด๋‚  ๊ฒƒ์ด๋‹ค.

์„ธ ๋ฒˆ์งธ ๋ฌธ์ œ๋Š” ๋ฃจํ‹ด์˜ ์ž‘๋™ ๋ฐฉ์‹์ด ๊ณ„์† ๋ณ€ํ•œ๋‹ค๋Š” ๊ฒƒ์ด๋‹ค. ๋ฃจํ‹ด ๋™์ž‘์ด ๋…ผ๋ธ”๋กœํ‚น ๋ฐฉ์‹์—์„œ ๋ธ”๋กœํ‚น ๋ฐฉ์‹์œผ๋กœ ๋ณ€๊ฒฝ๋œ๋‹ค๋ฉด, ๊ทธ ๋ฃจํ‹ด์„ ํ˜ธ์ถœํ•˜๋Š” ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ๋„ ์ƒˆ๋กœ์šด ๋ฐฉ์‹๊ณผ ๋งž๋„๋ก ๋ณ€๊ฒฝํ•ด์•ผ ํ•œ๋‹ค. ์ด์— ์ ํ•ฉํ•˜๊ฒŒ ๋ฃจํ‹ด์„ ๋‘ ๋ฒ„์ „์œผ๋กœ ๋‚˜๋ˆ„์–ด์•ผ ํ•œ๋‹ค. ์ด๋ฒคํŠธ ๊ธฐ๋ฐ˜ ์„œ๋ฒ„์—์„œ ๋ธ”๋กœํ‚น์€ ์น˜๋ช…์ ์ด๋‹ค. ๊ฐœ๋ฐœ์ž๋Š” ๊ฐ ์ด๋ฒคํŠธ๊ฐ€ ์‚ฌ์šฉํ•˜๋Š” API ๋ช…์„ธ๊ฐ€ ๋ฐ”๋€Œ๋Š”์ง€ ์ฃผ์˜ ๊นŠ๊ฒŒ ์‚ดํŽด์•ผ ํ•œ๋‹ค.

๋งˆ์ง€๋ง‰์œผ๋กœ, ๋น„๋™๊ธฐ ๋””์Šคํฌ I/O๊ฐ€ ๋Œ€๋ถ€๋ถ„์˜ ํ”Œ๋žซํผ์—์„œ ์‚ฌ์šฉ๋˜๊ธฐ๊นŒ์ง€๋Š” ๋งค์šฐ ์˜ค๋ž˜ ๊ฑธ๋ ธ์œผ๋ฉฐ, ์•„์ง๊นŒ์ง€๋„ ๋น„๋™๊ธฐ ๋„คํŠธ์›Œํฌ I/O๋Š” ์ผ๊ด€์„ฑ ์žˆ๊ฒŒ ์ ์šฉ๋˜์–ด ์žˆ์ง€ ์•Š๋‹ค. ์˜ˆ๋ฅผ ๋“ค๋ฉด, ๋ชจ๋“  ์ž…์ถœ๋ ฅ ์ฒ˜๋ฆฌ์— select()๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ์ด์ƒ์ ์ด์ง€๋งŒ, ์ผ๋ฐ˜์ ์œผ๋กœ ๋„คํŠธ์›Œํฌ ์š”์ฒญ์˜ ์ฒ˜๋ฆฌ์—๋Š” select(), ๋””์Šคํฌ I/O์—๋Š” AIO๊ฐ€ ์‚ฌ์šฉ๋˜๊ณ  ์žˆ๋‹ค.

node.js - dont block event loop

๋™์‹œ์„ฑ, ๋ณ‘๋ ฌ, ๋น„๋™๊ธฐ, ๋…ผ๋ธ”๋Ÿญํ‚น๊ณผ ์ปจ์…‰๋“ค