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()์ ๋ํด ์์๋์ด์ผ ํ ์ฌํญ์ด ๋ ๊ฐ์ง ์๋ค.
-
select()๋ฅผ ์ด์ํ๋ฉด ๋์คํฌ๋ฆฝํฐ์ ๋ํ ์ฝ๊ธฐ ๊ฐ๋ฅ ์ฌ๋ถ, ์ฐ๊ธฐ ๊ฐ๋ฅ ์ฌ๋ถ๋ฅผ ๊ฒ์ฌํ ์ ์๋ค. ์ ์(์ฝ๊ธฐ ๊ฐ๋ฅ ์ฌ๋ถ)๋ ์ฒ๋ฆฌํด์ผ ํ ํจํท์ ๋์ฐฉ ์ฌ๋ถ๋ฅผ ์ ์ ์๋๋ก ํ๋ค. ํ์(์ฐ๊ธฐ ๊ฐ๋ฅ ์ฌ๋ถ)๋ ์๋น์ค๊ฐ ์๋ต ์ ์ก์ด ๊ฐ๋ฅํ ์์ ์ ํ์ ํ ์ ์๋๋ก ํ๋ค. (์๋ฅผ ๋ค์ด, outbound queue๊ฐ ๊ฐ๋ ์ฐจ์ง ์์ ์ํ) -
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
๋์์ฑ, ๋ณ๋ ฌ, ๋น๋๊ธฐ, ๋ ผ๋ธ๋ญํน๊ณผ ์ปจ์ ๋ค