[Book] ๊ฒŒ์ž„ ์„œ๋ฒ„ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ๊ต๊ณผ์„œ - 3์žฅ ์†Œ์ผ“ ํ”„๋กœ๊ทธ๋ž˜๋ฐ (2)

2022. 2. 2. 18:14ยท๐Ÿ“ Book/โœ Game Server

3์žฅ ์†Œ์ผ“ ํ”„๋กœ๊ทธ๋ž˜๋ฐ

 

6. ๋…ผ๋ธ”๋ก ์†Œ์ผ“

์ผ๋Œ€์ผ ๋„คํŠธ์›Œํ‚น ํ”„๋กœ๊ทธ๋žจ์„ ๊ฐœ๋ฐœํ•  ๋•Œ๋Š” ๋ธ”๋กœํ‚น ์†Œ์ผ“์„ ์‚ฌ์šฉํ•ด๋„ ๋ฌด๋ฐฉํ•˜๋‹ค.

ํ•˜์ง€๋งŒ ๋„คํŠธ์›Œํ‚น์„ ํ•ด์•ผ ํ•˜๋Š” ๋Œ€์ƒ์ด ์—ฌ๋Ÿฟ์ด๋ผ๋ฉด ์–ด๋–ป๊ฒŒ ํ•ด์•ผ ํ• ๊นŒ?

 

๋‹คํ–‰ํžˆ ๋Œ€๋ถ€๋ถ„ ์šด์˜์ฒด์ œ์—์„œ๋Š” ์†Œ์ผ“ ํ•จ์ˆ˜๊ฐ€ ๋ธ”๋กœํ‚น๋˜์ง€ ์•Š๊ฒŒ ํ•˜๋Š” API๋ฅผ ์ถ”๊ฐ€๋กœ ์ œ๊ณตํ•œ๋‹ค. ์ด๋ฅผ ๋…ผ๋ธ”๋ก ์†Œ์ผ“์ด๋ผ ํ•œ๋‹ค.

๋…ผ๋ธ”๋ก ์†Œ์ผ“์„ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์€ ์•„๋ž˜์™€ ๊ฐ™๋‹ค.

void NonBlockSocketOperation()
{
    s = socket(TCP);
    ...;
    s.connect(...);
    // ๋…ผ๋ธ”๋ก ์†Œ์ผ“์œผ๋กœ ๋ณ€๊ฒฝ
    s.SetNonBlocking(true);
 
    while (true)
    {
        r = s.send(dest, data);
        if (r == EWOULDBLOCK)
        {
            // ๋ธ”๋กœํ‚น ๊ฑธ๋ฆด ์ƒํ™ฉ์ด์—ˆ๋‹ค. ์†ก์‹ ์„ ์•ˆ ํ–ˆ๋‹ค.
            continue;
        }
 
        if (r == OK)
        {
            // ๋ณด๋‚ด๊ธฐ ์„ฑ๊ณต์— ๋Œ€ํ•œ ์ฒ˜๋ฆฌ
        }
        else
        {
            // ๋ณด๋‚ด๊ธฐ ์‹คํŒจ์— ๋Œ€ํ•œ ์ฒ˜๋ฆฌ
        }
    }
}
  • ์†Œ์ผ“์„ ๋…ผ๋ธ”๋ก ์†Œ์ผ“์œผ๋กœ ๋ชจ๋“œ ์ „ํ™˜ํ•œ๋‹ค.
  • ๋…ผ๋ธ”๋ก ์†Œ์ผ“์— ๋Œ€ํ•ด ํ‰์†Œ์ฒ˜๋Ÿผ ์†ก์‹ , ์ˆ˜์‹ , ์—ฐ๊ฒฐ๊ณผ ๊ด€๋ จ๋œ ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•œ๋‹ค.
  • ์ด ํ•จ์ˆ˜ ํ˜ธ์ถœ์— ๋Œ€ํ•ด ์„ฑ๊ณต ํ˜น์€ would block ์˜ค๋ฅ˜ ๋‘˜ ์ค‘ ํ•˜๋‚˜๋ฅผ ๋ฌด์กฐ๊ฑด ์ฆ‰์‹œ ๋ฆฌํ„ดํ•œ๋‹ค.

 

์ƒ๋Œ€๋ฐฉ์—๊ฒŒ TCP ์ ‘์† ์—ญํ• ์„ ํ•˜๋Š” connect() ํ•จ์ˆ˜๋ฅผ ๋…ผ๋ธ”๋กœํ‚น์œผ๋กœ ์“ธ ๋•Œ๋Š” ์กฐ๊ธˆ ๋‹ค๋ฅด๋‹ค. ์™œ๋ƒํ•˜๋ฉด would block์ด ์†ก์ˆ˜์‹  ํ•จ์ˆ˜์—์„œ ๋ฆฌํ„ด๋œ๋‹ค๋ฉด ์•„๋ฌด ์ผ๋„ ์ผ์–ด๋‚˜์ง€ ์•Š์ง€๋งŒ, ์—ฐ๊ฒฐ ํ•จ์ˆ˜์—์„œ ๋ฆฌํ„ด๋œ๋‹ค๋ฉด ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•œ ๊ฒƒ์ด๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. ๊ทธ๋ž˜์„œ ์ž˜ ์—ฐ๊ฒฐ๋œ ๊ฒƒ์ธ์ง€ ํ™•์ธ์ด ํ•„์š”ํ•˜๋‹ค. ๋‹ค์‹œ connect()๋ฅผ ๋‹ค์‹œ ์‹œ๋„ํ•˜๋Š” ๊ฒƒ๋ณด๋‹จ 0๋ฐ”์ดํŠธ ์†ก์‹  ๋ฐฉ์‹์„ ํ†ตํ•ด ํ™•์ธํ•˜๋Š” ๊ฒƒ์ด ์ข‹๋‹ค.

void NonBlockSocketOperation()
{
    result = s.connect();
    if (result = = EWOULDBLOCK)
    {
        while (true)
        {
            byte emptyData[0]; // ๊ธธ์ด 0์ธ ๋ฐฐ์—ด
            result = s.send(emptyData);
            if (result == OK)
            {
                // ์—ฐ๊ฒฐ ์„ฑ๊ณต ์ฒ˜๋ฆฌ
            }
            else if (result == ENOTCONN)
            {
                // ์—ฐ๊ฒฐ์ด ์•„์ง ์ง„ํ–‰ ์ค‘์ด๋‹ค.
            }
            else
            {
                // ์—ฐ๊ฒฐ ์‹คํŒจ ์ฒ˜๋ฆฌ
            }
        }
    }
}
  • TCP๋Š” ์ŠคํŠธ๋ฆผ ๊ธฐ๋ฐ˜ ํ”„๋กœํ† ์ฝœ์ด๊ธฐ ๋•Œ๋ฌธ์— 0๋ฐ”์ดํŠธ๋ฅผ ๋ณด๋‚ด๋Š” ๊ฒƒ์€ ์‚ฌ์‹ค์ƒ ์•„๋ฌด๊ฒƒ๋„ ํ•˜์ง€ ์•Š๋Š” ์…ˆ์ด๋‹ค.
  • ์„ฑ๊ณต์„ ๋ฆฌํ„ดํ•˜๋ฉด TCP ์—ฐ๊ฒฐ์ด ๋˜์–ด ์žˆ๋‹ค๋Š” ์˜๋ฏธ์ด๋‹ค.
  • ENOTCONN์„ ๋ฆฌํ„ดํ•˜๋ฉด TCP ์—ฐ๊ฒฐ์ด ์ง„ํ–‰ ์ค‘์ด๋‹ค.
  • ๊ธฐํƒ€ ์˜ค๋ฅ˜ ์ฝ”๋“œ๊ฐ€ ๋‚˜์˜ค๋ฉด TCP ์—ฐ๊ฒฐ ์‹œ๋„๊ฐ€ ์‹คํŒจํ•œ ๊ฒƒ์ด๋‹ค.

 

๋…ผ๋ธ”๋ก ์†Œ์ผ“์„ ์‚ฌ์šฉํ•˜๋ฉด ํ•œ ์Šค๋ ˆ๋“œ์—์„œ ์—ฌ๋Ÿฌ ์†Œ์ผ“์„ ํ•œ๊บผ๋ฒˆ์— ๋‹ค๋ฃฐ ์ˆ˜ ์žˆ๋‹ค.

List<Socket> sockets;
 
void NonBlockSocketOperation()
{
    foreach(s in sockets) // ๊ฐ ์†Œ์ผ“์— ๋Œ€ํ•ด
    {
        // ๋…ผ๋ธ”๋ก ์ˆ˜์‹ . ์˜ค๋ฅ˜ ์ฝ”๋“œ์™€ ์ˆ˜์‹ ๋œ ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ›๋Š”๋‹ค.
        (result, data) = s.receive();
        if (data.length > 0) // ์ž˜ ์ˆ˜์‹ ํ–ˆ์œผ๋ฉด
        {
            print(data); // ์ถœ๋ ฅ
        }
        else if (result != EWOULDBLOCK)
        {
            // would block์ด ์•„๋‹ˆ๋ฉด ์˜ค๋ฅ˜๊ฐ€ ๋‚œ ๊ฒƒ์ด๋ฏ€๋กœ
            // ํ•„์š”ํ•œ ์ฒ˜๋ฆฌ๋ฅผ ํ•œ๋‹ค.
            ...;
        }
    }
}
  • ์ˆ˜์‹ ํ•  ๋ฐ์ดํ„ฐ๊ฐ€ ์—†์œผ๋ฉด would block ์˜ค๋ฅ˜๋ฅผ ๋ฆฌํ„ดํ•œ๋‹ค.

 

์˜ˆ์‹œ ์ฝ”๋“œ๋“ค์„ ์‹ค์ œ๋กœ ๊ตฌ๋™ํ•˜๋ฉด ํ•ด๋‹น ์Šค๋ ˆ๋“œ๋Š” ์†Œ์ผ“์ด would block์ธ ์ƒํƒœ์—์„œ๋Š” ๊ณ„์†ํ•ด์„œ ๋ฃจํ”„๋ฅผ ๋Œ๊ณ  CPU๋ฅผ ์‰ฌ์ง€ ๋ชปํ•˜๋Š” ๋ฐ”์œ ์ƒํƒœ๋กœ ๋งŒ๋“ ๋‹ค. ์ฆ‰, CPU ์ฝ”์–ด ํ•˜๋‚˜๊ฐ€ 100% ์‚ฌ์šฉ๋Ÿ‰์„ ์ฐจ์ง€ํ•œ๋‹ค. select()๋‚˜ poll() ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค๋ฉด CPU ํญ์ฃผ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ๋‹ค.

  • ์—ฌ๋Ÿฌ ์†Œ์ผ“ ์ค‘ ํ•˜๋‚˜๋ผ๋„ would block์ด์—ˆ๋˜ ์ƒํƒœ์— ๋ณ€ํ™”๊ฐ€ ์ผ์–ด๋‚˜๋ฉด, ์ฆ‰ ์†ก์‹  ๋ฒ„ํผ์— ๋นˆ ๊ณต๊ฐ„์ด ์ƒ๊ธฐ๊ฑฐ๋‚˜ ์ˆ˜์‹  ๋ฒ„ํผ์— ๋ญ”๊ฐ€๊ฐ€ ๋“ค์–ด์˜จ๋‹ค๋ฉด ๊ทธ ์ƒํ™ฉ์„ ์•Œ๋ ค ์ค€๋‹ค.
  • ํ˜น์€ ๊ทธ๊ฒƒ์„ ์•Œ๋ ค ์ฃผ๊ธฐ ์ „๊นŒ์ง€๋Š” ๋ธ”๋กœํ‚น ์ค‘์ด์–ด์„œ CPU ์‚ฌ์šฉ๋Ÿ‰ ํญ์ฃผ๋ฅผ ํ•ด๊ฒฐํ•œ๋‹ค.
List<Socket> sockets;
 
void NonBlockSocketOperation()
{
    while (true)
    {
        // 100๋ฐ€๋ฆฌ์ดˆ๊นŒ์ง€ ๋Œ€๊ธฐ
        // 1๊ฐœ๋ผ๋„ I/O ์ฒ˜๋ฆฌ๋ฅผ ํ•  ์ˆ˜ ์žˆ๋Š” ์ƒํƒœ๊ฐ€ ๋˜๋ฉด
        // ๊ทธ ์ „์—๋ผ๋„ ๋ฆฌํ„ด
        select(sockets, 100ms);
 
        foreach(s in sockets)
        {
            // ๋…ผ๋ธ”๋ก ์ˆ˜์‹ 
            (result, data) = s.receive();
            if (data.length > 0)
            {
                print(data);
            }
            else if (result != EWOULDBLOCK)
            {
                // ์†Œ์ผ“ ์˜ค๋ฅ˜ ์ฒ˜๋ฆฌ๋ฅผ ํ•œ๋‹ค.
            }
        }
    }
}

 

7. Overlapped I/O ํ˜น์€ ๋น„๋™๊ธฐ I/O

๋…ผ๋ธ”๋ก ์†Œ์ผ“์˜ ๋‹จ์ ์€ ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

  • ์†Œ์ผ“ I/O ํ•จ์ˆ˜๊ฐ€ ๋ฆฌํ„ดํ•œ ์ฝ”๋“œ๊ฐ€ would block์ธ ๊ฒฝ์šฐ ์žฌ์‹œ๋„ ํ˜ธ์ถœ ๋‚ญ๋น„๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.
  • ์†Œ์ผ“ I/O ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•  ๋•Œ ์ž…๋ ฅํ•˜๋Š” ๋ฐ์ดํ„ฐ ๋ธ”๋ก์— ๋Œ€ํ•œ ๋ณต์‚ฌ ์—ฐ์‚ฐ์ด ๋ฐœ์ƒํ•œ๋‹ค.

 

์ด๋Ÿฌํ•œ ๋‹จ์ ์„ ํ•ด๊ฒฐํ•ด์ฃผ๋Š” ๊ฒƒ์ด Overlapped ๋˜๋Š” Asynchronous(๋น„๋™๊ธฐ) I/O์ด๋‹ค.

  • ์†Œ์ผ“์— ๋Œ€ํ•ด Overlapped ์•ก์„ธ์Šค๋ฅผ ๊ฑธ๊ณ  ์„ฑ๊ณตํ–ˆ๋Š”์ง€ ํ™•์ธ ํ›„ ์„ฑ๊ณตํ–ˆ์œผ๋ฉด ๊ฒฐ๊ด๊ฐ’์„ ์–ป์–ด ์™€์„œ ๋‚˜๋จธ์ง€๋ฅผ ์ฒ˜๋ฆฌํ•œ๋‹ค.
  • ์™„๋ฃŒ๋˜๊ธฐ ์ „๊นŒ์ง€ Overlapped status ๊ฐ์ฒด๊ฐ€ ๋ฐ์ดํ„ฐ ๋ธ”๋ก์„ ์ค‘๊ฐ„์— ํ›ผ์†ํ•˜์ง€ ๋ง์•„์•ผ ํ•œ๋‹ค.
void OverlappedSocketOperation()
{
    var overlappedSendStatus;
    (result, length) = s.OverlappedSend( // ๋ธ”๋กœํ‚น ์†Œ์ผ“ ๊ทธ๋Œ€๋กœ ์‚ฌ์šฉ
        data,
        overlappedSendStatus);
 
    // ์ฆ‰์‹œ ๋ฆฌํ„ด
    if (length > 0)
    {
        // ๋ณด๋‚ด๊ธฐ ์„ฑ๊ณต
    }
    else if (result == WSA_IO_PENDING)
    {
        // Overlapped I/O๊ฐ€ ์ง„ํ–‰ ์ค‘
        while (true)
        {
            (result, length) =
                GetOverlappedResult(s,
                    overlappedSendStatus);
            if (length > 0)
            {
                // ์ž˜ ๋ณด๋ƒˆ๋‹ค.
            }
            else
            {
                // ์•„์ง I/O pending์ด๋‹ค.
            }
        }
    }
}

 

๋…ผ๋ธ”๋ก ์†Œ์ผ“๊ณผ Overlapped I/O์€ ์†Œ์ผ“ ๊ฐœ์ˆ˜๊ฐ€ ๋งŽ์„ ๋•Œ ๋ฃจํ”„๋ฅผ ๋Œ๋ฉฐ ์ฒ˜๋ฆฌํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์„ฑ๋Šฅ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.

์ด๋Ÿฌํ•œ ๋ฃจํ”„ ์—†์ด ํ•œ ๋ฒˆ์— ๋๋‚ด๋Š” ๋ฐฉ๋ฒ•์€ ์—†์„๊นŒ?

๊ทธ๋ž˜์„œ ๋“ฑ์žฅํ•œ ๊ฒƒ์ด IOCP์™€ epoll์ด๋‹ค.

 

8. epoll

epoll์€ ํ•ด๋‹น ์†Œ์ผ“์ด I/O ๊ฐ€๋Šฅ ์ƒํƒœ๊ฐ€ ๋˜๋ฉด ์ด๋ฅผ ๊ฐ์ง€ํ•ด์„œ ์‚ฌ์šฉ์ž์—๊ฒŒ ์•Œ๋ฆผ์„ ํ•ด์ฃผ๋Š” ์—ญํ• ์„ ํ•œ๋‹ค.

 

epoll

  • ์†Œ์ผ“ 2๊ฐ€ I/O ๊ฐ€๋Šฅ์ด ๋˜๋Š” ์ˆœ๊ฐ„ epoll์€ ์ด ์ƒํ™ฉ์„ ๋‚ด์žฅ ํ์— push ํ•œ๋‹ค.
  • ์‚ฌ์šฉ์ž๋Š” epoll์—์„œ ์ด๋Ÿฌํ•œ ์ด๋ฒคํŠธ ์ •๋ณด๋ฅผ pop ํ•  ์ˆ˜ ์žˆ๋‹ค.

๋”ฐ๋ผ์„œ ์†Œ์ผ“์ด 1๋งŒ ๊ฐœ๋ผ๊ณ  ํ•ด๋„ ์ด ์ค‘์—์„œ I/O ๊ฐ€๋Šฅ์ด ๋œ ๊ฒƒ๋“ค๋งŒ ์–ป์„ ์ˆ˜ ์žˆ๋‹ค.

 

์˜ˆ์‹œ ์ฝ”๋“œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

epoll = new epoll();
foreach(s in sockets)
{
    epoll.add(s, GetUserPtr(s));
}
 
events = epoll.wait(100ms);
 
foreach(event in events)
{
    s = event.socket;
    // ์œ„ epoll.add์— ๋“ค์–ด๊ฐ”๋˜ ๊ฐ’์„ ์–ป๋Š”๋‹ค.
    userPtr = event.userPtr;
    // ์ˆ˜์‹ ? ์†ก์‹ ?
    type = event.type;
    if (type = = ReceiveEvent)
    {
        (result, data) = s.recv();
        if (data.length > 0)
        {
            // ์ˆ˜์‹ ๋œ ๋ฐ์ดํ„ฐ๋ฅผ ์ฒ˜๋ฆฌํ•œ๋‹ค.
            Process(userPtr, s, data);
        }
    }
}
  • ๋ชจ๋“  ์†Œ์ผ“์— ๋Œ€ํ•œ select() ํ•จ์ˆ˜ ๋Œ€์‹  epoll์—์„œ ์ด๋ฒคํŠธ๋ฅผ ๊บผ๋‚ด ์˜ค๋Š” wait() ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•œ๋‹ค. ์ด ํ•จ์ˆ˜๋Š” ์‚ฌ์šฉ์ž๊ฐ€ ์›ํ•˜๋Š” ์‹œ๊ฐ„๊นŒ์ง€๋งŒ ๋ธ”๋กœํ‚น๋˜๋ฉฐ ๊ทธ์ „์— ์ด๋ฒคํŠธ๊ฐ€ ์ƒ๊ธฐ๋Š” ์ฆ‰์‹œ ๋ฆฌํ„ดํ•œ๋‹ค. ์ถœ๋ ฅ ๊ฐ’์—๋Š” ๊บผ๋‚ด์˜จ ์ด๋ฒคํŠธ๋“ค์ด ์žˆ๋‹ค.
  • ๊ฐ ์ด๋ฒคํŠธ์— ๋Œ€ํ•ด ๋ฃจํ”„๋ฅผ ๋Œ๋ฉฐ ์ด๋ฒคํŠธ๊ฐ€ ๊ฐ€๋ฆฌํ‚ค๋Š” ์†Œ์ผ“ ๊ฐ์ฒด์™€ ์‚ฌ์šฉ์ž ์ •์˜ ๊ฐ’์„ ๊บผ๋‚ด์™€ ์ฒ˜๋ฆฌํ•œ๋‹ค.

 

๊ทธ๋Ÿฌ๋‚˜ ์œ„ ์ฝ”๋“œ๊ฐ€ ์ด์ƒ์ ์œผ๋กœ ๋ณด์ด์ง€๋งŒ ํ˜„์‹ค์€ ๋‹ค๋ฅด๋‹ค. ์†Œ์ผ“์˜ ์†ก์‹  ๋ฒ„ํผ๊ฐ€ ๋นˆ ๊ณต๊ฐ„์ด ์—†๋Š” ์ˆœ๊ฐ„์„ ์œ ์ง€ํ•˜๋Š” ์‹œ๊ฐ„์ด ์ƒ๋Œ€์ ์œผ๋กœ ์งง์•„์„œ ๊ฑฐ์˜ ๋Œ€๋ถ€๋ถ„์€ ์†ก์‹  ๊ฐ€๋Šฅ ์ƒํƒœ์ด๋‹ค. ์ด๋Ÿฌํ•œ ํŠน์ง• ๋•Œ๋ฌธ์— ํ•„์š” ์ด์ƒ์˜ ๋ฃจํ”„๋ฅผ ๋˜ ๋Œ๊ฒŒ ๋œ๋‹ค. ์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ๋ ˆ๋ฒจ(level) ํŠธ๋ฆฌ๊ฑฐ ๋Œ€์‹  ์—์ง€(edge) ํŠธ๋ฆฌ๊ฑฐ๋ฅผ ์จ์•ผ ํ•œ๋‹ค.

  • ๋ ˆ๋ฒจ ํŠธ๋ฆฌ๊ฑฐ๋Š” '์†Œ์ผ“์ด I/O ๊ฐ€๋Šฅํ•˜๋‹ค'๋ฅผ ์˜๋ฏธํ•˜๊ณ  ์—์ง€ ํŠธ๋ฆฌ๊ฑฐ๋Š” ์†Œ์ผ“์ด I/O ๊ฐ€๋Šฅ์ด ์•„๋‹ˆ์—ˆ๋Š”๋ฐ, ์ด์ œ ๊ฐ€๋Šฅ์ด ๋˜์—ˆ๋‹ค'๋ฅผ ์˜๋ฏธํ•œ๋‹ค. ๋”ฐ๋ผ์„œ ๊ฐ€๋Šฅ์œผ๋กœ ๋ณ€ํ•˜๋Š” ์ˆœ๊ฐ„์—๋งŒ ๊บผ๋‚ด์ง„๋‹ค.
  • ์—์ง€ ํŠธ๋ฆฌ๊ฑฐ๋ฅผ ์“ธ ๋•Œ๋Š” ์†Œ์ผ“์€ ๋…ผ๋ธ”๋ก์œผ๋กœ ๋ฏธ๋ฆฌ ์„ค์ •๋˜์–ด ์žˆ์–ด์•ผ ํ•˜๋ฉฐ I/O ํ˜ธ์ถœ์„ ํ•œ ๋ฒˆ๋งŒ ํ•˜์ง€ ๋ง๊ณ  would block์ด ๋ฐœ์ƒํ•  ๋•Œ๊นŒ์ง€ ๋ฐ˜๋ณตํ•ด์•ผ ํ•œ๋‹ค.
foreach(event in events)
{
    s = event.socket;
    // ์œ„ epoll.add์— ๋“ค์–ด๊ฐ”๋˜ ๊ฐ’์„ ์–ป๋Š”๋‹ค.
    userPtr = event.userPtr;
    // ์ˆ˜์‹ ? ์†ก์‹ ?
    type = event.type;
    if (type = = ReceiveEvent)
    {
        while (true)
        {
            (result, data) = s.recv();
            if (data.length > 0)
            {
                // ์ˆ˜์‹ ๋œ ๋ฐ์ดํ„ฐ๋ฅผ ์ฒ˜๋ฆฌํ•œ๋‹ค.
                Process(userPtr, s, data);
            }
            if (result == EWOULDBLOCK)
                break;
        }
    }
}

 

9. IOCP

IOCP๋Š” ์†Œ์ผ“์˜ Overlapped I/O๊ฐ€ ์™„๋ฃŒ๋˜๋ฉด ์ด๋ฅผ ๊ฐ์ง€ํ•ด์„œ ์‚ฌ์šฉ์ž์—๊ฒŒ ์•Œ๋ ค์ฃผ๋Š” ์—ญํ• ์„ ํ•œ๋‹ค.

 

IOCP

  • ์†Œ์ผ“ 2๊ฐ€ ์™„๋ฃŒ๋˜๋Š” ์ˆœ๊ฐ„ IOCP๋Š” ์ด ์ƒํ™ฉ์„ ๋‚ด์žฅ ํ์— push ํ•œ๋‹ค.
  • ์‚ฌ์šฉ์ž๋Š” IOCP์—์„œ I/O๊ฐ€ ์™„๋ฃŒ๋˜์—ˆ์Œ์„ ์•Œ๋ ค์ฃผ๋Š” ์™„๋ฃŒ ์‹ ํ˜ธ๋ฅผ pop ํ•  ์ˆ˜ ์žˆ๋‹ค.

๋”ฐ๋ผ์„œ ์†Œ์ผ“์ด 1๋งŒ ๊ฐœ๋ผ๊ณ  ํ•ด๋„ ์ด ์ค‘์—์„œ I/O ๊ฐ€๋Šฅ์ด ๋œ ๊ฒƒ๋“ค๋งŒ ์–ป์„ ์ˆ˜ ์žˆ๋‹ค.

 

์˜ˆ์‹œ ์ฝ”๋“œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

epoll๊ณผ ๊ฑฐ์˜ ์œ ์ง€ํ•˜์ง€๋งŒ ์ฐจ์ด์ ์ด ์žˆ๋‹ค๋ฉด, epoll์€ I/O ๊ฐ€๋Šฅ์ธ ๊ฒƒ์„ ์•Œ๋ ค ์ฃผ์ง€๋งŒ IOCP๋Š” I/O ์™„๋ฃŒ์ธ ๊ฒƒ์„ ์•Œ๋ ค์ค€๋‹ค.

iocp = new iocp();
foreach(s in sockets)
{
    iocp.add(s, GetUserPtr(s));
    s.OverlappedReceive(data[s],
        receiveOverlapped[s]);
}

events = iocp.wait(100ms);
 
foreach(event in events)
{
    // ์œ„ iocp.add์— ๋“ค์–ด๊ฐ”๋˜ ๊ฐ’์„ ์–ป๋Š”๋‹ค.
    userPtr = event.userPtr;
    ov = event.overlappedPtr;
    s = GetSocketFromUserPtr(userPtr);
 
    if (ov = = receiveOverlapped[s])
    {
        // overlapped receive๊ฐ€ ์„ฑ๊ณตํ–ˆ์œผ๋‹ˆ,
        // ๋ฐ›์€ ๋ฐ์ดํ„ฐ๋ฅผ ์ฒ˜๋ฆฌํ•œ๋‹ค.
        Process(s, userPtr, data[s]);
 
        s.OverlappedReceive(data[s],
            receiveOverlapped[s]);
    }
}

 

IOCP๋Š” ์˜ค๋ž˜์ „์— ๋‚˜์˜จ API์ด๊ธฐ ๋•Œ๋ฌธ์— epoll๋ณด๋‹ค ๊ตฌํ˜„์ด ๋ณต์žกํ•œ ๊ธฐ๋Šฅ์ด ์žˆ์ง€๋งŒ ๋ฐ˜๋Œ€๋กœ ์„ฑ๋Šฅ์ƒ ์œ ๋ฆฌํ•œ ๊ธฐ๋Šฅ๋„ ์žˆ๋‹ค.

๋ฐ”๋กœ ์Šค๋ ˆ๋“œ ํ’€๋ง์„ ์‰ฝ๊ฒŒ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ์ ์ด๋‹ค.

 

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

 

์ €์ž‘์žํ‘œ์‹œ (์ƒˆ์ฐฝ์—ด๋ฆผ)
'๐Ÿ“ Book/โœ Game Server' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€
  • [Book] ๊ฒŒ์ž„ ์„œ๋ฒ„ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ๊ต๊ณผ์„œ - 5์žฅ ๊ฒŒ์ž„ ๋„คํŠธ์›Œํ‚น
  • [Book] ๊ฒŒ์ž„ ์„œ๋ฒ„ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ๊ต๊ณผ์„œ - 4์žฅ ๊ฒŒ์ž„ ์„œ๋ฒ„์™€ ํด๋ผ์ด์–ธํŠธ
  • [Book] ๊ฒŒ์ž„ ์„œ๋ฒ„ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ๊ต๊ณผ์„œ - 3์žฅ ์†Œ์ผ“ ํ”„๋กœ๊ทธ๋ž˜๋ฐ (1)
  • [Book] ๊ฒŒ์ž„ ์„œ๋ฒ„ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ๊ต๊ณผ์„œ - 2์žฅ ์ปดํ“จํ„ฐ ๋„คํŠธ์›Œํฌ (2)
Blxxming
Blxxming
CS ์ง€์‹๊ณผ ๊ณต๋ถ€ํ•˜๋‹ค ๋ฐฐ์šด ๊ฒƒ, ๊ฒฝํ—˜ํ•œ ๊ฒƒ ๋“ฑ์„ ๊ธฐ๋กํ•˜๋Š” ๋ธ”๋กœ๊ทธ์ž…๋‹ˆ๋‹ค.
  • Blxxming
    ๐Ÿ’ก๋ฒˆ๋œฉ๐Ÿ’ก
    Blxxming
  • ์ „์ฒด
    ์˜ค๋Š˜
    ์–ด์ œ
  • ๊ณต์ง€์‚ฌํ•ญ

    • Tech Interview
    • ๐Ÿ“š Tech (246)
      • ๐Ÿ“ Computer Science (96)
        • โœ OS (12)
        • โœ Network & Web (10)
        • โœ Database (11)
        • โœ Data Structure (6)
        • โœ Algorithm (40)
        • โœ Design Pattern (9)
        • โœ Cloud Computing (3)
        • โœ (5)
      • ๐Ÿ“ Language (73)
        • โœ Language (6)
        • โœ C & C++ (11)
        • โœ C# (19)
        • โœ JAVA (37)
      • ๐Ÿ“ Game (43)
        • โœ Computer Graphics (2)
        • โœ Unity (14)
        • โœ Unreal (26)
        • โœ (1)
      • ๐Ÿ“ Book (34)
        • โœ Effective (3)
        • โœ Game Server (16)
        • โœ Clean Code (14)
        • โœ (1)
  • hELLOยท Designed By์ •์ƒ์šฐ.v4.10.0
Blxxming
[Book] ๊ฒŒ์ž„ ์„œ๋ฒ„ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ๊ต๊ณผ์„œ - 3์žฅ ์†Œ์ผ“ ํ”„๋กœ๊ทธ๋ž˜๋ฐ (2)
์ƒ๋‹จ์œผ๋กœ

ํ‹ฐ์Šคํ† ๋ฆฌํˆด๋ฐ”