<aside> ๐Ÿงญ

์ด ๋ฌธ์„œ๋Š” IOCP๋Š” ์†์— ์ต์—ˆ์ง€๋งŒ epoll์€ ์ฒ˜์Œ์ธ ์‚ฌ๋žŒ์„ ์œ„ํ•œ ๊ฒƒ์ด๋‹ค. ๋ชจ๋“  ์„ค๋ช…์„ "IOCP์—์„œ๋Š” ์–ด๋• ๋Š”๋ฐ, epoll์—์„œ๋Š” ์–ด๋–ป๊ฒŒ ๋˜๋Š”๊ฐ€"์˜ ๋Œ€๋น„๋กœ ํ•œ๋‹ค.

๋ชฉ์ ์€ epoll ์ผ๋ฐ˜๋ก ์ด ์•„๋‹ˆ๋ผ ์šฐ๋ฆฌ ์„œ๋ฒ„์˜ Transport_Epoll.cpp๋ฅผ ์ฝ์„ ์ˆ˜ ์žˆ๊ฒŒ ๋งŒ๋“œ๋Š” ๊ฒƒ์ด๋‹ค. ๊ทธ๋ž˜์„œ ๊ฐœ๋… ํ•˜๋‚˜๋งˆ๋‹ค ๊ทธ ๊ฐœ๋…์ด ์‹ค์ œ๋กœ ๋‚˜ํƒ€๋‚œ ์ฝ”๋“œ ์ค„๋ฒˆํ˜ธ๋ฅผ ๋ถ™์˜€๋‹ค.

</aside>

<aside> ๐Ÿ“Œ

๋ฒ”์œ„ โ€” ๋ฆฌ๋ˆ…์Šค epoll, ๋ ˆ๋ฒจ ํŠธ๋ฆฌ๊ฑฐ ๊ธฐ์ค€. ์ค„๋ฒˆํ˜ธ ์ธ์šฉ์€ ์ „๋ถ€ IOCP_Server/IOCP_Server/Transport_Epoll.cpp์ด๋ฉฐ, ๋‹ค๋ฅธ ํŒŒ์ผ์€ ์ด๋ฆ„์„ ๋ฐํ˜”๋‹ค. selectยทpoll์—์„œ epoll์— ์ด๋ฅด๋Š” ๊ณ„๋ณด๋Š” 0์žฅ์— ์žˆ๋‹ค.

์•„์ง ์•ˆ ์“ด ๊ฒƒ โ€” EPOLLETยทEPOLLEXCLUSIVEยทSO_REUSEPORT๋Š” ์šฐ๋ฆฌ ์ฝ”๋“œ์— ์—†๋‹ค. ์™œ ์—†๋Š”์ง€๋Š” 8์žฅ์—.

์ด ๊ฐœ๋…์ด ์‹ค์ œ๋กœ ๋ฌด์—‡์„ ๋ถ€์‰ˆ๋Š”์ง€๋Š” ๋”ฐ๋กœ ์žˆ๋‹ค โ†’ 3. ๋‘ ๋ชจ๋ธ ์ฐจ์ด๊ฐ€ ํ„ฐ์ง„ ๊ณณ ยท ์ „์ฒด ์š”์•ฝ์€ 1. ์™œ ์˜ฎ๊ฒผ๋‚˜ ยท ๊ฒฐ๊ณผ

</aside>


0. select์™€ poll

์œˆ๋„์šฐ์—์„œ select๋ฅผ ๋ฒ„๋ฆฌ๊ณ  IOCP๋กœ ๊ฐ”๋˜ ์ด์œ ๊ฐ€ ์žˆ์—ˆ๋‹ค. ๋ฆฌ๋ˆ…์Šค์—์„œ select๋ฅผ ๋ฒ„๋ฆฌ๊ณ  epoll๋กœ ๊ฐ€๋Š” ์ด์œ ๊ฐ€ ๊ทธ๊ฒƒ๊ณผ ๊ฐ™๋‹ค. ์ด ์žฅ์€ ๊ทธ ๊ณ„๋ณด๋ฅผ ํ•œ ๋ฒˆ์— ํ›‘๋Š”๋‹ค. ์ด๋ฏธ ์•„๋Š” ์‚ฌ๋žŒ์€ 1์žฅ์œผ๋กœ ๊ฑด๋„ˆ๋›ฐ์–ด๋„ ๋œ๋‹ค.

select ยท poll ยท epoll

select ยท poll ยท epoll์€ ์ „๋ถ€ ์ค€๋น„ ํ†ต์ง€๋‹ค. "์ฝ์„ ์ˆ˜ ์žˆ๊ฒŒ ๋๋‹ค"๊นŒ์ง€๋งŒ ์•Œ๋ ค์ฃผ๊ณ  recv๋Š” ๋‚ด๊ฐ€ ๋ถ€๋ฅธ๋‹ค. ๋ฒ„ํผ๋„ ์ฒ˜์Œ๋ถ€ํ„ฐ ๋๊นŒ์ง€ ๋‚ด ๊ฒƒ์ด๋‹ค.

์…‹์˜ ์ฐจ์ด๋Š” ํ•˜๋‚˜๋ฟ์ด๋‹ค โ€” ๋ˆ„๊ฐ€ ์ค€๋น„๋๋Š”์ง€ ์•Œ์•„๋‚ด๋Š” ๋ฐฉ๋ฒ•. ์™„๋ฃŒ ํ†ต์ง€์ธ IOCP์™€๋Š” ๊ณ„์—ด ์ž์ฒด๊ฐ€ ๋‹ค๋ฅด๊ณ , ๊ทธ ์ฐจ์ด๊ฐ€ 1์žฅ๊ณผ 2์žฅ์˜ ๋‚ด์šฉ์ด๋‹ค.

select โ€” ๋งค๋ฒˆ ์ฒ˜์Œ๋ถ€ํ„ฐ

select๋Š” ๊ฐ์‹œํ•  ์†Œ์ผ“ ๋ฌถ์Œ์„ ๋งค ํ˜ธ์ถœ๋งˆ๋‹ค ์ปค๋„์— ๋„˜๊ธด๋‹ค. ์ปค๋„์€ ๊ทธ ๋ฌถ์Œ์„ ์ฒ˜์Œ๋ถ€ํ„ฐ ๋๊นŒ์ง€ ํ›‘์œผ๋ฉฐ ์†Œ์ผ“๋งˆ๋‹ค ์ƒํƒœ๋ฅผ ํ™•์ธํ•œ๋‹ค. ์ค€๋น„๋œ ๊ฒƒ์ด ํ•˜๋‚˜๋ฟ์ด์–ด๋„ ์ „๋ถ€๋ฅผ ๋ˆ๋‹ค.

์—ฌ๊ธฐ์— ๋ˆˆ์— ์•ˆ ๋ณด์ด๋Š” ๋น„์šฉ์ด ํ•˜๋‚˜ ๋” ๋ถ™๋Š”๋‹ค. ์•„๋ฌด๊ฒƒ๋„ ์ค€๋น„๋˜์ง€ ์•Š์•˜์œผ๋ฉด ์ž ๋“ค์–ด์•ผ ํ•˜๋ฏ€๋กœ, ์ปค๋„์€ ์†Œ์ผ“ ํ•˜๋‚˜ํ•˜๋‚˜์˜ ๋Œ€๊ธฐํ์— "๋ฐ์ดํ„ฐ ์˜ค๋ฉด ๊นจ์›Œ๋ผ"๋ฅผ ๊ฑธ์–ด ๋‘”๋‹ค. ๊ทธ๋ฆฌ๊ณ  ๋ฐ˜ํ™˜ํ•  ๋•Œ ๊ทธ๊ฒƒ์„ ์ „๋ถ€ ๋—€๋‹ค. ๊ฑธ์—ˆ๋‹ค ๋–ผ๊ธฐ๋ฅผ ๋งค ํ˜ธ์ถœ๋งˆ๋‹ค n๋ฒˆ์”ฉ ๋ฐ˜๋ณตํ•œ๋‹ค.

๊ฒฐ๊ณผ๊ฐ€ ์ž…๋ ฅ์„ ๋ฎ์–ด์“ฐ๋Š” ๋ฌธ์ œ๋„ ์žˆ๋‹ค. fd_set์„ "์ด๊ฒƒ๋“ค์„ ๋ด ๋‹ฌ๋ผ"๊ณ  ๋„˜๊ธฐ๋ฉด ๋Œ์•„์˜ฌ ๋•Œ๋Š” "์ด๊ฒƒ๋“ค์ด ์ค€๋น„๋๋‹ค"๋กœ ๋ฐ”๋€Œ์–ด ์žˆ๋‹ค. ์›๋ณธ์ด ์‚ฌ๋ผ์ง€๋‹ˆ ๋‹ค์Œ ๋ฃจํ”„ ์ „์— ๋ฌถ์Œ์„ ์ฒ˜์Œ๋ถ€ํ„ฐ ๋‹ค์‹œ ์ฑ„์›Œ์•ผ ํ•œ๋‹ค.

// ํ•œ ๋ฐ”ํ€ด์— n๊ฐœ๋ฅผ ์„ธ ๋ฒˆ ๋งŒ์ง„๋‹ค
while (running) {
    FD_ZERO(&readSet);
    for (auto& s : sessions) FD_SET(s.fd, &readSet);            // โ‘  ๋‹ค์‹œ ์ฑ„์šฐ๊ธฐ
    select(nfds, &readSet, NULL, NULL, &tv);                    // โ‘ก ์ปค๋„์ด ์ „๋ถ€ ํ›‘๊ธฐ
    for (auto& s : sessions) if (FD_ISSET(s.fd, &readSet)) ...  // โ‘ข ๊ฒฐ๊ณผ ํ›‘๊ธฐ
}

๊ฐœ์ˆ˜ ์ œํ•œ๋„ ์žˆ๋‹ค. ์œˆ๋„์šฐ๋Š” 64, ๋ฆฌ๋ˆ…์Šค๋Š” 1024์ด๊ณ , ๋‘˜์€ ์„ฑ์งˆ์ด ๋‹ค๋ฅด๋‹ค.

// winsock2.h:132 โ€” ๊ฐ€๋“œ๊ฐ€ ์žˆ๋‹ค = ๋ฎ์–ด์“ฐ๋ผ๊ณ  ๋งŒ๋“  ์ž๋ฆฌ
#ifndef FD_SETSIZE
#define FD_SETSIZE      64
#endif

// bits/typesizes.h:103 โ€” ๊ฐ€๋“œ ์—†๋Š” ๋ฌด์กฐ๊ฑด ์ •์˜
#define __FD_SETSIZE   1024

์œˆ๋„์šฐ๋Š” winsock2.h๋ฅผ include ํ•˜๊ธฐ ์ „์— ๋‹ค์‹œ ์ •์˜ํ•˜๋ฉด ์˜ฌ๋ผ๊ฐ„๋‹ค. ๋ฆฌ๋ˆ…์Šค๋Š” ์•ˆ ๋œ๋‹ค. sys/select.h์˜ ๊ตฌ์กฐ์ฒด๊ฐ€ ๋‚ด๋ถ€ ์ด๋ฆ„ __FD_SETSIZE๋กœ ํฌ๊ธฐ๊ฐ€ ์ •ํ•ด์ง€๊ณ  ์šฐ๋ฆฌ์—๊ฒŒ ๋ณด์ด๋Š” FD_SETSIZE๋Š” ๊ทธ๊ฒƒ์„ ๋ฐ›์•„ ๋งŒ๋“ค์–ด์งˆ ๋ฟ์ด๋ผ, ๋ฐ–์—์„œ ์•„๋ฌด๋ฆฌ ์ •์˜ํ•ด๋„ ๊ตฌ์กฐ์ฒด๋Š” ๊ทธ๋Œ€๋กœ๋‹ค.

<aside> โš ๏ธ

์ˆซ์ž๋ฅผ ์˜ฌ๋ฆฌ๋Š” ๊ฒƒ์ด ํ•ด๋ฒ•์ด ๋œ ์ ์€ ์—†๋‹ค. FD_SETSIZE๋Š” "๋ช‡ ๊ฐœ๊นŒ์ง€ ๋‹ด์„ ์ˆ˜ ์žˆ๋‚˜"์ด๊ณ  select๋Š” ๋‹ด๊ธด ๊ฒƒ ์ „๋ถ€๋ฅผ ๋งค๋ฒˆ ํ›‘์œผ๋ฏ€๋กœ, ๊ทธ ์ˆซ์ž๊ฐ€ ๊ณง ๋น„์šฉ์˜ ํฌ๊ธฐ๋‹ค. ๋‹ด์„ ์ˆ˜ ์žˆ๋Š” ๊ฐœ์ˆ˜๋ฅผ ๋Š˜๋ฆฌ๋ฉด ๋‚ญ๋น„๋„ ๊ฐ™์ด ๋Š˜์–ด๋‚œ๋‹ค.

์œˆ๋„์šฐ์—์„œ 64๋ฅผ ๋„˜๊ธฐ๋ ค๊ณ  64๊ฐœ์”ฉ ์Šค๋ ˆ๋“œ์— ์ชผ๊ฐœ ๋ถ™์ด๋˜ ์‹œ์ ˆ์ด ์žˆ์—ˆ๋‹ค. ๊ทธ๋Ÿฌ๋ฉด ์Šค๋ ˆ๋“œ ์ˆ˜๊ฐ€ ์„ธ์…˜ ์ˆ˜๋ฅผ ๋”ฐ๋ผ๊ฐ„๋‹ค โ€” 5,000๋ช…์ด๋ฉด ์Šค๋ ˆ๋“œ 79๊ฐœ๋‹ค. IOCP๋Š” ์ด ๋ง‰๋‹ค๋ฅธ ๊ณจ๋ชฉ์„ ์—†์• ๋ ค๊ณ  ๋‚˜์™”๋‹ค.

</aside>

poll โ€” ์ž๋ฃŒ๊ตฌ์กฐ๋งŒ ๊ณ ์ณค๋‹ค

fd_set ๋น„ํŠธ๋งˆ์Šคํฌ๋ฅผ ๋ฐฐ์—ด๋กœ ๋ฐ”๊พผ ๊ฒƒ์ด poll์ด๋‹ค.

struct pollfd {
    int   fd;
    short events;   // ๋‚ด ๊ด€์‹ฌ์‚ฌ
    short revents;  // ์ปค๋„์ด ์ฑ„์›Œ ์ฃผ๋Š” ๋‹ต
};