FrontPage|FindPage|TitleIndex|RecentChanges|RSS epoll
 
1 Áغñ
2 socket ÇÁ·Î±×·¡¹Ö ±âº»
3 ºñµ¿±â ÀÔÃâ·Â (Asyncronous I/O) & ÀÔÃâ·Â ´ÙÁßÈ­ (I/O Multiplexing)
4 select
5 select ¿Í poll ±×¸®°í epoll. ±× Â÷ÀÌ
6 epoll ÇÁ·Î±×·¡¹Ö È帧
7 epoll ÇÔ¼öµé
8 epoll References

ºóÆúµµ ¾Æ´Ï°í, ÀÌÆúÀ̶õ ´ëü ¹«¾ùÀϱî?


´ç½ÅÀº ¼­¹öÇÑ´ë·Î ¸î ¸íÀÇ µ¿½ÃÁ¢¼ÓÀÚ¸¦ ¼ö¿ëÇÒ ¼ö ÀÖ½À´Ï±î? ÃÖ±Ù¿¡ ÀÎÅͳݿ¡ ¶°µ¹¾Æ´Ù´Ï´Â [http]c10k_problemÀº ´ë´ç 10K, Áï 1¸¸¸íÀÇ µ¿½ÃÁ¢¼Ó(concurrent users)À» ¹Þ¾Æº¸ÀÚ´Â ¹®Á¦´Ù. ¼­¹ö ÇÁ·Î±×·¡¹ÖÀ» ÇØ º» »ç¶÷À̶ó¸é ÀÌ°Ô ±×¸® ¸¸¸¸ÇÑ ¹®Á¦°¡ ¾Æ´Ï¶ó´Â °ÍÀ» Á÷°¨ÇÒ µí --;


¿äÁòÀÇ Massive ¿Â¶óÀΰÔÀÓÀº 'ºÐ»êó¸®'°¡ ±âº»À̶ó ÇÑ ´ë¿¡¼­ ¸¹Àº ÀÌ¿ëÀÚ¸¦ Ä¿¹öÇϱ⺸´Ù´Â ¿©·¯´ë°¡ ÇϳªÀÇ ¼¼Æ®·Î½á ±¸¼ºÇÏ´Â °ÍÀÌ ÀαⰡ ÀÖ°í ´Ù¼öÀÇ Ä¿³Ø¼Çº¸´Ù´Â ¼Ò¼ö Ä¿³Ø¼Ç¿¡¼­ÀÇ ´ë¿ë·® Àü¼ÛÀÌ ´õ Áß¿äÇÑ ¿ä¼ÒÀ̱⵵ ÇÏ´Ù.


c10k problem¿¡ ³ª¶ÇÇÑ °ü½ÉÀ» °¡Áö°Ô µÇ¾ú°í, epoll ÀÌ ÃÖ±Ù ±ÞºÎ»óÇÏ´Â ¼Ö·ç¼ÇÀ¸·Î ÀαⰡ Àִٱ⿡ ÇÑ ¹ø Æĺ¸ÀÚ ÇÏ°í °á½ÉÇÏ°í ÀÌ ±ÛÀ» ½ÃÀÛÇß´Ù. ¸¶Ä§ wiki¿¡µµ °ü½ÉÀÌ ÀÖ´ø Â÷¶ó, wiki °øºÎµµ ÇÒ °âÇؼ­ epoll À» ¿¬±¸ÇÏ´Â °úÁ¤À» ÀÌ wiki¿¡ ´ã¾Æ º¸°íÀÚ ÇÑ´Ù.


1 Áغñ #


* ´©±¸¸¦ À§ÇÑ epoll Àΰ¡?


epollÀº 'ÇÑ ´ëÀÇ ¼­¹ö¿¡¼­ ¾ÆÁÖ¸¹Àº µ¿½ÃÁ¢¼ÓÀÚ¸¦ ó¸®Çϱâ À§ÇÑ ¼ö´Ü'ÀÌ´Ù. ÀÌ¹Ì ´ç½ÅÀÌ ±× ¼ö´ÜÀ» ¾Ë°í ÀÖ´Ù¸é - epoll ÀÌ°Ç ¾Æ´Ï°Ç - ÀÌ ±ÛÀº º°·Î µµ¿òÀÌ ¾ÈµÉµíÇÏ´Ù. µ¿½ÃÁ¢¼ÓÀÚ°¡ õ¸íÀ» ³ÑÁö¾Ê´Â´Ù¸é ±¸´Ú´Ù¸® ¹æ¹ýÀ» ÀÌ¿ëÇÏ´Â °Í°ú Å« Â÷ÀÌ°¡ ¾øÀ¸¸®¶ó º»´Ù.


¶ÇÇÑ, epollÀº Linux ÇÁ·Î±×·¡¸ÓÀÇ µµ±¸ÀÌ´Ù. M$ window$ ȯ°æÀÇ °³¹ßÀÚ¶ó¸é ÀÌ¹Ì iocp ¶ó´Â ÈǸ¢ÇÑ µµ±¸°¡ ÀÖ°í ?FreeBSD¶ó¸é kqueue¶ó´Â µµ±¸°¡ ÀÖ´Ù. °¢°¢ÀÇ OS¿¡ ¸Â´Â µµ±¸¸¦ ¼±ÅÃÇÏÀÚ.


* »çÀüÁغñ

epoll(4) is a new API introduced in Linux kernel 2.5.44.  Its interface  should be finalized in Linux kernel 2.5.66.

epollÀº Linux Ä¿³Î 2.5.44 ¿¡¼­ ¼Ò°³µÈ »õ·Î¿î APIÀ̸ç, 2.5.66 ¿¡¼­ ¿Ï¼ºµÇ¾ú´Ù. ±¸¹öÀü Ä¿³ÎÀ̶ó¸é ÆÐÄ¡¸¦ ÇÒ ¼öµµ ÀÖ°ÚÀ¸³ª ±×³É Linux 2.6.x ¸¦ ±¸ÇØ´Ù ¾²ÀÚ. ;)

[biscuit@fedora-dumoyi epoll]$ uname -a
Linux fedora-dumoyi 2.6.5-1.358 #1 Sat May 8 09:04:50 EDT 2004 i686 i686 i386 GNU/Linux

[biscuit@fedora-dumoyi epoll]$ nm -D /lib/libc.so.6 | grep epoll
000bd740 T epoll_create
000bd780 T epoll_ctl
000bd7d0 T epoll_wait

nm µµ±¸¸¦ ÀÌ¿ëÇÏ¿©, /lib/libc.so.6 À» ´ýÇÁÇغ» °á°ú, Àß ÀÖ´Ù ^^.


°°Àº 2.6.x ¶ó°í ÇÏ´õ¶óµµ Ä¿³Î ¼³Á¤¿¡¼­ ºüÁú¼öµµÀִµ¥, ÀÌ °æ¿ì¿¡´Â ¹°·Ð Ä¿³Î ÄÄÆÄÀÏÀ» ´Ù½Ã ÇØÁÖ¾î¾ß ÇÑ´Ù --; General setup > Configure standard kernel features > Enable eventpoll support ¸¦ Yes·Î ÇÏÀÚ. Ä¿³Î¼³Ä¡ Âü°í : http://www.joinc.co.kr/modules/moniwiki/wiki.php/mz_gentoo


Linux Kernel 2.5.22 ÀÌ»óÀÌ ÇÊ¿äÇÏ´Ù.
glibc 2.3.2 ÀÌ»óÀÌ ÇÊ¿äÇÏ´Ù. ?RedHat 9.x ´Â Áö¿øÇÏ°í ÀÖ´Ù.
gcc 3.3.x ÀÌ»óÀÌ ÇÊ¿äÇÏ´Ù. Ãß°¡ÀûÀ¸·Î ÀÌ ¹®¼­¿¡¼­´Â C++°ú STLÀ» ÀÌ¿ëÇÏ°í ÀÖÀ¸¹Ç·Î ¿¹Á¦¸¦ ¸ðµÎ ÄÄÆÄÀÏ Çغ¸±â À§Çؼ­´Â g++ °ú libstdc++ ÀÌ ¼³Ä¡µÇ¾î ÀÖ¾î¾ß ÇÑ´Ù.


2 socket ÇÁ·Î±×·¡¹Ö ±âº» #


* ÀÌ °÷À» °¡º±°Ô ÀÐ°í ¿Â´Ù : socketÇÁ·Î±×·¡¹Ö±âº»


3 ºñµ¿±â ÀÔÃâ·Â (Asyncronous I/O) & ÀÔÃâ·Â ´ÙÁßÈ­ (I/O Multiplexing) #


* ÀÌ °÷À» °¡º±°Ô ÀÐ°í ¿Â´Ù : ºñµ¿±âÀÔÃâ·Â(?AsyncIo) * ÀÌ °÷À» °¡º±°Ô ÀÐ°í ¿Â´Ù : ÀÔÃâ·Â ´ÙÁßÈ­(?IoMultiplex)


4 select #


* ÀÌ °÷À» °¡º±°Ô ÀÐ°í ¿Â´Ù : Select ¸¦ ÀÌ¿ëÇÑ ¼­¹ö ¸¸µé±â (?SelectModel)


5 select ¿Í poll ±×¸®°í epoll. ±× Â÷ÀÌ #


select´Â fd_setÀ̶ó´Â ±¸Á¶Ã¼¸¦ ÅëÇØ fdµéÀ» µî·ÏÇÏ°Ô µÇ´Âµ¥, ºÒÇàÇÏ°Ôµµ ÀÌ fd_set´Â bitmask¶ó¼­ 1024°³±îÁö¸¸ µî·ÏÇÒ ¼ö ÀÖ´Ù (Ä¿³ÎÀ» ¶â¾î°íÄ¡¸é ´Ã¸± ¼ö ÀÖ´Ù´Â ¸»µµ µé¾îº»°Å °°±â´Â ÇÏ´Ù¸¸...). °Ô´Ù°¡ À̺¥Æ® ¹ß»ýÀ» °¨ÁöÇϱâ À§ÇØ ³»ºÎÀûÀ¸·Î ¼øÂ÷°Ë»ç¸¦ ½ÃÇàÇϹǷΠµ¿½ÃÁ¢¼ÓÀÌ ´Ã¾î³¯¼ö·Ï ºÒ¸®ÇØÁø´Ù.


poll ÇÔ¼ö´Â, °ü½ÉÀÖ¾îÇÏ´Â fd µéÀÇ ±¸Á¶Ã¼¹è¿­À» ÆĶó¹ÌÅÍ·Î ¹Þ´Âµ¥, ¸ðµç fdµé¿¡ ´ëÇØ ¼øÂ÷°Ë»ç¸¦ ½ÃÇàÇϹǷΠ¿ª½Ã ¸¶Âù°¡ÁöÀÌ´Ù.


select³ª pollÀ̳ª, ¶Ç epollÀ̳ª °ü½ÉÀÖ´Â fd¸¦ ÁË´Ù µî·ÏÇØµÎ°í ±×Áß ÇÑ°³ À̻󿡼­ »ç°ÇÀÌ ¹ß»ýÇÏ´Â °ÍÀ» °¨ÁöÇѴٴµ¥´Â Â÷ÀÌ°¡ ¾ø´Ù. ±×·¯³ª ¾î¶² fd¿¡¼­ »ç°ÇÀÌ ¹ß»ýÇßÀ» °æ¿ì, select´Â ¾î´À ³à¼®¿¡¼­ ¹ß»ýÇÑ »ç°ÇÀÎÁö¸¦ ã±â À§ÇØ Àüü fd ¿¡ ´ëÇؼ­ FD_ISSET ·çÇÁ¸¦ µ¹·Á¾ß ÇÏÁö¸¸, epoll_wait´Â »ç°ÇÀÌ ¹ß»ýÇÑ fdµé¸¸ÀÇ ±¸Á¶Ã¼ ¹è¿­À» ¼ÂÆÃÇØÁֹǷÎ, º¸´Ù ÇÕ¸®ÀûÀÌ´Ù.


6 epoll ÇÁ·Î±×·¡¹Ö È帧 #


* epoll fd »ý¼º : epoll_create() * ¿¬°á ¹Þ±â (listen, accept)
  1. listen ¿ë fd »ý¼º ¹× Áغñ : socket(), bind(), setsockopt()
  2. epoll¿¡ µî·Ï : epoll_ctl(..., EPOLL_CTL_ADD, ... )
  3. listen()
  4. epoll_wait¸¦ ÅëÇØ, fd_listen ¿¡ »ç°Ç¹ß»ý(Áï, ´©±º°¡ Á¢¼Ó½ÃµµÇÔ)À» °¨ÁöÇÏ¿© Á¢¼Ó¹ÞÀ½ : accept()
  5. accept·ÎºÎÅÍ ³Ñ¾î¿Â fd¿¡ Åë½ÅÁغñ : fcntl()
  6. epoll¿¡ »õ·Î¿î fd µî·Ï : epoll_ctl(..., EPOLL_CTL_ADD, ... )

* ¿¬°á Çϱâ (connect)
  1. »çÀüÁغñ(»ó´ë¹æ ipÁÖ¼Ò, port¹øÈ£µî) ±×¸®°í ¿¬°á : connect()
  2. ¿¬°á¼º°øÇϸé connect·ÎºÎÅÍ ³Ñ¾î¿Â fd¿¡ Åë½ÅÁغñ : fcntl()
  3. epoll¿¡ »õ·Î¿î fd µî·Ï : epoll_ctl(..., EPOLL_CTL_ADD, ... )

* ¿¬°á ²÷±â (connect)
  1. ¿¬°áÀ» ²÷°í ½Í°Å³ª, ¿¬°áÀÌ ²÷±è »ç°Ç ¹ß»ý ¶Ç´Â ¿¡·¯¹ß»ý : read(), epoll_wait() ¿¡¼­ °¨Áö
  2. epoll¿¡¼­ ÇØ´ç fd »èÁ¦ : epoll_ctrl(..., EPOLL_CTL_DEL, ...)
  3. ¿¬°á ´ÝÀ½ : close()

* epoll Á¾·á : close(), epoll µµ FILEÀ̱⠶§¹®¿¡ ±×³É ´ÝÀ¸¸é µÈ´Ù ;)

* Àбâ (read)
  1. ÀÐÀ» µ¥ÀÌŸ µµÂøÇßÀ½À» °¨Áö : epoll_wait()
  2. µ¥ÀÌŸ Àбâ : read()
  3. Àд µµÁß ¹ß»ýÇÏ´Â ¿¡·¯Ã³¸®, ÇÊ¿ä½Ã ¿¬°á²÷±â

* ¾²±â (write)
  1. º¸³¾ µ¥ÀÌÅÍ°¡ ¹ß»ýÇÑ °æ¿ì Send Buffer¿¡ ÀÏ´Ü ÀúÀå
  2. º¸³»µµ µÈ´Ù´Â ½ÅÈ£¸¦ °¨Áö : epoll_wait()
  3. µ¥ÀÌÅÍ Àü¼Û : write()
    1. Àü¼Û µµÁß ¹ß»ýÇÏ´Â ¿¡·¯Ã³¸®, ÇÊ¿ä½Ã ¿¬°á²÷±â ȤÀº WOULDBLOCK ó¸®

  4. Âü°í 1, WOULDBLOCK ÀÎ °æ¿ì´Â ¿¡·¯Áö¸¸ ¿¡·¯Ã³¸®ÇÏÁö ¾Ê°í, ´Ü¼øÈ÷ ¸®ÅÏÇÏ°í ±â´Ù¸®´Ù°¡, EPOLLOUT ½ÅÈ£°¡ ´Ù½Ã ¹ß»ýÇßÀ» °æ¿ì¿¡ µ¥ÀÌÅ͸¦ Àü¼ÛÇϵµ·Ï ÇÑ´Ù.
    Âü°í 2, Send Buffering (]?SendBuffer])


7 epoll ÇÔ¼öµé #


* nm À¸·Î ´ýÇÁÇغ» °á°ú¿¡¼­ ´«Ä¡Ã«°ÚÁö¸¸, epoll °ü·Ã ÇÔ¼ö´Â µþ¶û 3°³´Ù! ÀÌ 3°³ÀÇ ÇÔ¼ö¿Í struct epoll_event ±¸Á¶Ã¼¸¸ ¾Ë¸é epoll Á¤º¹Àº ´«¾Õ¿¡ ÀÖ´Ù°í Çصµ °ú¾ðÀÌ ¾Æ´Ï´Ù. ;)


epoll_create
#include <sys/epoll.h>

int epoll_create(int size);

epoll_create´Â size ¸¸Å­ÀÇ Ä¿³ÎÆú¸µ°ø°£À» ¸¸µå´Â ÇÔ¼öÀÌ´Ù. ¸®ÅÏ°ªÀº ±×³É Á¤¼ö°ªÀε¥ fd_epollÀ̶ó°í ºÎ¸£±â·Î ÇÏÀÚ. ÀÌ fd_epoll ¸¦ ÀÌ¿ëÇؼ­ ¾ÕÀ¸·Î ´Ù¸¥ Á¶ÀÛµéÀ» ÇÏ°Ô µÈ´Ù.

int fd_epoll;
bool is_epoll_init = false;

int EpollInit(int size)
{       
        if((fd_epoll = epoll_create(size)) > 0) is_epoll_init = true;
        return fd_epoll;
}

size °ªÀº Á¤¼öÀε¥ ¹«ÀÛÁ¤ Å« ¼ö¸¦ ¾µ ¼ö´Â ¾ø´Ù. ¿¹»óµÇ´Â ÃÖ´ë µ¿½ÃÁ¢¼Ó ¼ö·Î ÇÏ¸é µÉÅÙµ¥, ¿î¿µÃ¼Á¦°¡ ÀÌ ¼ýÀÚ¸¦ Çã¿ëÇÏ´ÂÁö ¸ÕÀú È®ÀÎÇØÁÖ¾î¾ßÇÑ´Ù. ¼­¹öÀÇ ÇÑ°è(ServerLimits)¸¦ ¼÷ÁöÇÏ°í, Àû´çÇÑ °ªÀ» ½á Áְųª ¼­¹öÇѰ踦 ´Ã·Á! ÁÖ¾î¾ß ÇÑ´Ù.


À§ ÄÚµùÀº, fd_epoll °ú is_epoll_int ¸¦ Àü¿ªº¯¼ö·Î »© ³ù´Âµ¥, ³ªÁß¿¡ class ·Î ¸¸µé±â À§Çؼ­ÀÌ´Ù. ÀÌÈÄ¿¡ class ?TEpoll À» ¸¸µé°ÍÀÌ°í, new ?TEpoll(size)·Î Á¢±ÙÇÏ°Ô ÇÒ °èȹ.


epoll_ctl
#include <sys/epoll.h>

int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);

epoll_ctlÀº epollÀÌ °ü½ÉÀ» °¡Á®ÁÖ±æ ¹Ù¶ó´Â fd¿Í ±× fd¿¡¼­ ¹ß»ýÇÏ´Â °ü½ÉÀÖ´Â »ç°ÇÀÇ Á¾·ù¸¦ µî·ÏÇÏ´Â ÀÎÅÍÆäÀ̽º. epoll_event ±¸Á¶Ã¼¸¦ »ìÆ캸ÀÚ.
typedef union epoll_data {
    void *ptr;
    int fd;
    __uint32_t u32;
    __uint64_t u64;
} epoll_data_t;

struct epoll_event {
    __uint32_t events;  /* Epoll events */
    epoll_data_t data;  /* User data variable */
};

°ø¿ëü Çϳª¿Í 32ºñÆ® Á¤¼ö¸¦ °¡Áö´Â Æò¹üÇÑ ±¸Á¶Ã¼Àε¥, »ç°ÇÀº (epoll_event).events¸¦ ÀÌ¿ëÇÑ´Ù. º¸Åë ¼­¹ö¿¡¼­´Â ÀÔÃâ·Â ½ÃÁ¡¿¡ °ü½ÉÀÌ ¸¹±â ¶§¹®¿¡, ¾Æ·¡ ¿¹Á¦¿¡¼­´Â IN/OUT/ERR ¼¼°¡Áö À̺¥Æ®¸¦ ¼³Á¤Çϵµ·Ï Çß´Ù.
int EpollAdd(const int fd)
{       
        struct epoll_event ev;
        
        ev.events  = EPOLLIN | EPOLLOUT | EPOLLERR;
        ev.data.fd = fd;
        
        return epoll_ctl(fd_epoll, EPOLL_CTL_ADD, fd, &ev);
}


epoll_wait
ÀÌÁ¦ epollÀÇ ÇÙ½É, epoll_wait¸¦ »ìÆ캸ÀÚ.
#include <sys/epoll.h>

int  epoll_wait(int  epfd,  struct epoll_event * events, int maxevents, int timeout);

epoll_waitÇÔ¼ö´Â °ü½ÉÀÖ´Â fd µé¿¡ ¹«½¼ÀÏÀÌ ÀϾ´ÂÁö Á¶»çÇÑ´Ù. ´Ù¸¸ ±× °á°ú´Â ¾Õ¼­ »ìÆ캻¹Ù¿Í °°ÀÌ select³ª poll°ú´Â Â÷ÀÌ°¡ ÀÖ´Ù. »ç°ÇµéÀÇ ¸®½ºÆ®¸¦ (epoll_event).events[] ÀÇ ¹è¿­·Î Àü´ÞÇÑ´Ù. ¶Ç, ½ÇÁ¦ µ¿½ÃÁ¢¼Ó¼ö¿Í´Â »ó°ü¾øÀÌ maxevents ÆĶó¹ÌÅÍ·Î ÃÖ´ë ¸î°³±îÁöÀÇ event¸¸ ó¸®ÇÒ °ÍÀÓÀ» ÁöÁ¤ÇØ ÁÖµµ·Ï ÇÏ°í ÀÖ´Ù.


¸¸¾à ÇöÀç Á¢¼Ó¼ö°¡ 1¸¸À̶ó¸é ÃÖ¾ÇÀÇ °æ¿ì 1¸¸°³ÀÇ ¿¬°á¿¡¼­ »ç°ÇÀÌ ¹ß»ýÇÒ °¡´É¼ºµµ Àֱ⠶§¹®¿¡ 1¸¸°³ÀÇ events[] ¹è¿­À» À§ÇØ ¸Þ¸ð¸®¸¦ È®º¸ÇØ ³õ¾Æ¾ßÇÏÁö¸¸, ÀÌ maxevents ÆĶó¹ÌÅ͸¦ ÅëÇØ, Çѹø¿¡ ó¸®Çϱæ Èñ¸ÁÇÏ´Â ¼ýÀÚ¸¦ Á¦ÇÑÇÒ ¼ö ÀÖ´Ù.


timeoutÀº, epoll_waitÀÇ µ¿ÀÛƯ¼ºÀ» ÁöÁ¤ÇØÁÖ´Â Áß¿äÇÑ ¿ä¼ÒÀε¥, ¹Ð¸®¼¼ÄÁµå ´ÜÀ§·Î ÁöÁ¤ÇØÁÖµµ·Ï µÇ¾î ÀÖ´Ù. ÀÌ ½Ã°£¸¸Å­ »ç°Ç¹ß»ýÀ» ±â´Ù¸®¶ó´Â ÀǹÌÀε¥, ±â´Ù¸®´Â µµÁß¿¡ »ç°ÇÀÌ ¹ß»ýÇϸé Áï½Ã ¸®ÅϵȴÙ. ÀÌ °ª¿¡ (-1)À» ÁöÁ¤ÇØÁÖ¸é ¿µ¿øÈ÷ »ç°ÇÀ» ±â´Ù¸®°í(blocking), 0À» ÁöÁ¤ÇØÁÖ¸é, »ç°ÇÀÌ ÀְǾø°Ç Á¶»ç¸¸ ÇÏ°í Áï½Ã ¸®ÅÏÇÑ´Ù (Áï ±â´Ù¸®Áö ¾Ê´Â´Ù).


°£´ÜÇÑ Ã¤Æü­¹öÀÇ °æ¿ì¸¦ »ìÆ캸ÀÚ. ¼­¹ö°¡ ¾î¶°ÇÑ ÀÏÀ» ÇؾßÇÏ´Â ½ÃÁ¡Àº ÀÌ¿ëÀÚ ´©±º°¡°¡ µ¥ÀÌÅ͸¦ º¸³»¿ÔÀ» ¶§Àε¥, ¾Æ¹«µµ ¾Æ¹«¸»µµ ÇÏÁö ¾Ê´Â´Ù¸é ¼­¹ö´Â ±»ÀÌ ÇÁ·Î¼¼½ÌÀ» ÇÒ ÀÌÀ¯°¡ ¾ø´Ù. ÀÌ·²¶§ timeoutÀ» (-1)·Î ÁöÁ¤Çصΰí ÀÌ¿ëÀÚµéÀÇ ÀÔ·ÂÀÌ ¾ø´Â µ¿¾È ¿î¿µÃ¼Á¦¿¡ ÇÁ·Î¼¼½Ì ŸÀÓÀ» ³Ñ±âµµ·Ï ÇÑ´Ù.


¿Â¶óÀΰÔÀÓ(ƯÈ÷ MMORPG)ÀÇ °æ¿ì¿¡´Â, ÀÌ¿ëÀÚÀÇ ÀÔ·ÂÀÌ ÀüÇô ¾ø´Â µµÁßÀ̶ó°í ÇÏ´õ¶óµµ, ¸ó½ºÅÍ¿¡ °ü·ÃµÈ ó¸®, ÀûÀýÇÑ ÀúÀå, ´Ù¸¥ ¼­¹ö¿ÍÀÇ Åë½ÅµéÀ» ÇØ¾ß ÇϹǷΠÀûÀýÇÑ timeout (ÇÊÀÚÀÇ °æ¿ì¿¡´Â 1/100 sec, Áï 10ms¸¦ ¼±È£ÇÑ´Ù)À» ÁöÁ¤ÇØ ÁÖµµ·Ï ÇÑ´Ù.


¹º°¡ÀÇ ÇÁ·Î¼¼½ÌÀ» ÁÖ·Î Çϸ鼭 Àá±ñÀá±ñ Åë½ÅÀ̺¥Æ®¸¦ ó¸®ÇÏ°íÀÚ ÇÏ´Â °æ¿ì, Áï ÇÁ·Î¼¼½ºÀÇ CPU Á¡À¯¸¦ ³ô°ÔÇؼ­ ¹«¾ð°¡¸¦ ÇÏ°í ½ÍÀº °æ¿ì¿¡´Â, timeout 0À» ¼³Á¤ÇÏ¿© CPU¸¦ µ¶Á¡Çϵµ·Ï ¼³°èÇÒ ¼öµµ ÀÖ´Ù.


º°µµ thread¸¦ ±¸¼ºÇÏ¿© ÀÌ thread °¡ ÀÔÃâ·ÂÀ» Àü´ãÇϵµ·Ï ÇÁ·Î±×·¥À» ÀÛ¼ºÇÏ°íÀÚ ÇÏ´Â °æ¿ì¿¡´Â, ´ç¿¬È÷ timeoutÀ» (-1)·Î ¼³Á¤ÇÏ¿© ³²´Â ½Ã°£À» ´Ù¸¥ thread, ȤÀº ¿î¿µÃ¼Á¦¿¡ µ¹·Á ÁÖµµ·Ï ÇÑ´Ù.


¾Æ·¡ ¿¹Á¦´Â, epoll_waitÀ» ÀüÇüÀûÀ¸·Î ±¸ÇöÇØ º»°ÍÀÌ´Ù.
#define MAX_EVENTS  100 // ÃÖ´ë 100°³¸¦ Çѹø¿¡ ó¸®ÇÒ °ÍÀÌ´Ù.

struct epoll_event events[MAX_EVENTS];
int nfds, n;

for(;;){
    // ¹ß»ýÇÑ »ç°ÇÀÇ °¹¼ö¸¦ ¾ò¾î³½´Ù. 0ÀÎ °æ¿ì´Â ¾Æ¹«Àϵµ ¹ß»ýÇÏÁö ¾ÊÀº °Í
    nfds = epoll_wait(fd_epoll, events, MAX_EVENTS, 10);

    if(nfds < 0) {
        // critical error
        fprintf(stderr, "epoll_wait() error : %s\n", strerror(errno));
        exit(-1);
    }

    // ¾Æ¹«Àϵµ ÀϾÁö ¾Ê¾Ò´Ù.
    if(nfds == 0){
        // idle 
        continue;
    }

    for(n=0; n < nfds; ++n) OnEvent(&events[n]);
}

epoll_wait¸¦ È£ÃâÇÏ°í, ±× °á°ú·Î À̺¥Æ®°¡ ¹ß»ýÇÑ fdÀÇ °¹¼ö°¡ µ¹¾Æ¿À¸ç ¾î¶² fdµéÀÎÁö¿Í ¾î¶² À̺¥Æ®µéÀÎÁö´Â epoll_event ±¸Á¶Ã¼ ¹è¿­¿¡ ´ã°ÜÁø´Ù. ±× °¹¼ö¸¸Å­ÀÇ À̺¥Æ® 󸮸¦ ÇØ ÁÖµµ·Ï Çß´Ù.


?OnEvent()´Â À̺¥Æ® 󸮸¦ ´ã´çÇÒ ½ÇÁ¦ ÇÔ¼ö. Client class¸¦ ±¸¼ºÇÏ°í, ±× °´Ã¼¿Í ¹Ù·Î ¿¬°á½ÃÅ°µµ·Ï ÀÛ¼ºÇÏ¸é ¹«³­ÇÒ µí(Á¢¼Ó ¿¬°áº°·Î class ?TClientÀÇ °´Ã¼¸¦ »ý¼ºÇÏ°í map< fd, ?TClient *> ·Î °ü¸®¸¦ ÇÑ´Ù¸é ¾Æ·¡¿Í °°ÀÌ ÀÛ¼º).
#include <map>

using namespace std;

class TClient 
{
    ...
};

map<int, TClient *> mapClient;
TClient *tmpClient;

...
...

nfds = epoll_wait(...);

...

for(n=0; n < nfds; ++n){ 
    tmpClient = mapClient[events[n]->data.fd];

    if(tempClient) tmpClient->OnEvent(&events[n]);
    else ... // ¿¡·¯Ã³¸®
}


?OnEvent()ÀÇ ±¸Çö
int OnEvent(const struct epoll_event *event)
{
    int nread;
    char buf[1024];     

    if( event->events & EPOLLIN ){
        // ³ªÁß¿¡ OnRead(); ·Î ¹Ù²Ü°ÍÀÌ´Ù.
        nread = read(event->data.fd, buf, 1024);
        
        if( nread < 1){
            fprintf(stdout, "nread returns : %d\n", nread);
         } else {
            fprintf(stdout, "data : %s\n", buf);
            buf[0] = 0;
         }
    }
    if( event->events & EPOLLOUT){
        // ³ªÁß¿¡ OnWrite(); ·Î ¹Ù²Ü°ÍÀÌ´Ù.
    }
    if( event->events & EPOLLERR){
        // ³ªÁß¿¡ OnError(); ·Î ¹Ù²Ü°ÍÀÌ´Ù.
    }

    return 1;
}

±¸ÇöÀº Ưº°ÇÑ ³»¿ëÀº ¾ø°í, ´Ù¸¸ °¢ eventµé¿¡ ´ëÇؼ­ ÇØ´ç ºñÆ®°¡ ¼Â µÇ¾î ÀÖ´ÂÁö È®ÀÎÇϵµ·Ï ÇÏ°í ÀÖ°í, EPOLLIN À̺¥Æ®, Áï µ¥ÀÌÅÍ°¡ ¼ö½ÅµÇ¾úÀ»¶§ Àо È­¸é¿¡ Ç¥½ÃÇϵµ·Ï Çß´Ù.



8 epoll References #

* epoll : ¼³Ä¡Çϱâ http://blog.naver.com/evonit.do?Redirect=Log&logNo=80001543695
* epoll°ú ´Ù¸¥¹æ½Ä ºñ±³ : http://www.xmailserver.org/linux-patches/nio-improve.html
* [http]JoinC : http://www.joinc.co.kr/modules/moniwiki/wiki.php/epoll
* The C10k Problem : http://www.kegel.com/c10k.html
* libevent¿¡ ´ëÇÏ¿©, ¼ÒÄϸ𵨠¼º´Éºñ±³ : http://www.monkey.org/~provos/libevent/
* likesylph´ÔÀÇ epoll : http://php.chol.com/%7Elikesylph/wiki.php/epoll

last modified 2004-06-21 10:21:12
EditText|FindPage|DeletePage|LikePages|