- 1 Áغñ
- 2 socket ÇÁ·Î±×·¡¹Ö ±âº»
- 3 ºñµ¿±â ÀÔÃâ·Â (Asyncronous I/O) & ÀÔÃâ·Â ´ÙÁßÈ (I/O Multiplexing)
- 4 select
- 5 select ¿Í poll ±×¸®°í epoll. ±× Â÷ÀÌ
- 6 epoll ÇÁ·Î±×·¡¹Ö È帧
- 7 epoll ÇÔ¼öµé
- 8 epoll References
ºóÆúµµ ¾Æ´Ï°í, ÀÌÆúÀ̶õ ´ëü ¹«¾ùÀϱî?
´ç½ÅÀº ¼¹öÇÑ´ë·Î ¸î ¸íÀÇ µ¿½ÃÁ¢¼ÓÀÚ¸¦ ¼ö¿ëÇÒ ¼ö ÀÖ½À´Ï±î? ÃÖ±Ù¿¡ ÀÎÅͳݿ¡ ¶°µ¹¾Æ´Ù´Ï´Â
c10k_problemÀº ´ë´ç 10K, Áï 1¸¸¸íÀÇ µ¿½ÃÁ¢¼Ó(concurrent users)À» ¹Þ¾Æº¸ÀÚ´Â ¹®Á¦´Ù. ¼¹ö ÇÁ·Î±×·¡¹ÖÀ» ÇØ º» »ç¶÷À̶ó¸é ÀÌ°Ô ±×¸® ¸¸¸¸ÇÑ ¹®Á¦°¡ ¾Æ´Ï¶ó´Â °ÍÀ» Á÷°¨ÇÒ µí --;
¿äÁòÀÇ Massive ¿Â¶óÀΰÔÀÓÀº 'ºÐ»êó¸®'°¡ ±âº»À̶ó ÇÑ ´ë¿¡¼ ¸¹Àº ÀÌ¿ëÀÚ¸¦ Ä¿¹öÇϱ⺸´Ù´Â ¿©·¯´ë°¡ ÇϳªÀÇ ¼¼Æ®·Î½á ±¸¼ºÇÏ´Â °ÍÀÌ ÀαⰡ ÀÖ°í ´Ù¼öÀÇ Ä¿³Ø¼Çº¸´Ù´Â ¼Ò¼ö Ä¿³Ø¼Ç¿¡¼ÀÇ ´ë¿ë·® Àü¼ÛÀÌ ´õ Áß¿äÇÑ ¿ä¼ÒÀ̱⵵ ÇÏ´Ù.
c10k problem¿¡ ³ª¶ÇÇÑ °ü½ÉÀ» °¡Áö°Ô µÇ¾ú°í, epoll ÀÌ ÃÖ±Ù ±ÞºÎ»óÇÏ´Â ¼Ö·ç¼ÇÀ¸·Î ÀαⰡ Àִٱ⿡ ÇÑ ¹ø Æĺ¸ÀÚ ÇÏ°í °á½ÉÇÏ°í ÀÌ ±ÛÀ» ½ÃÀÛÇß´Ù. ¸¶Ä§ wiki¿¡µµ °ü½ÉÀÌ ÀÖ´ø Â÷¶ó, wiki °øºÎµµ ÇÒ °âÇؼ epoll À» ¿¬±¸ÇÏ´Â °úÁ¤À» ÀÌ wiki¿¡ ´ã¾Æ º¸°íÀÚ ÇÑ´Ù.
* ´©±¸¸¦ À§ÇÑ 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 À» ´ýÇÁÇغ» °á°ú, Àß ÀÖ´Ù ^^.
Linux Kernel 2.5.22 ÀÌ»óÀÌ ÇÊ¿äÇÏ´Ù.
glibc 2.3.2 ÀÌ»óÀÌ ÇÊ¿äÇÏ´Ù.
?RedHat 9.x ´Â Áö¿øÇÏ°í ÀÖ´Ù.
gcc 3.3.x ÀÌ»óÀÌ ÇÊ¿äÇÏ´Ù. Ãß°¡ÀûÀ¸·Î ÀÌ ¹®¼¿¡¼´Â C++°ú STLÀ» ÀÌ¿ëÇÏ°í ÀÖÀ¸¹Ç·Î ¿¹Á¦¸¦ ¸ðµÎ ÄÄÆÄÀÏ Çغ¸±â À§Çؼ´Â g++ °ú libstdc++ ÀÌ ¼³Ä¡µÇ¾î ÀÖ¾î¾ß ÇÑ´Ù.
2 socket ÇÁ·Î±×·¡¹Ö ±âº» #
3 ºñµ¿±â ÀÔÃâ·Â (Asyncronous I/O) & ÀÔÃâ·Â ´ÙÁßÈ (I/O Multiplexing) #
* ÀÌ °÷À» °¡º±°Ô ÀÐ°í ¿Â´Ù : ºñµ¿±âÀÔÃâ·Â(
?AsyncIo)
* ÀÌ °÷À» °¡º±°Ô ÀÐ°í ¿Â´Ù : ÀÔÃâ·Â ´ÙÁßÈ(
?IoMultiplex)
* ÀÌ °÷À» °¡º±°Ô ÀÐ°í ¿Â´Ù : 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)
- listen ¿ë fd »ý¼º ¹× Áغñ : socket(), bind(), setsockopt()
- epoll¿¡ µî·Ï : epoll_ctl(..., EPOLL_CTL_ADD, ... )
- listen()
- epoll_wait¸¦ ÅëÇØ, fd_listen ¿¡ »ç°Ç¹ß»ý(Áï, ´©±º°¡ Á¢¼Ó½ÃµµÇÔ)À» °¨ÁöÇÏ¿© Á¢¼Ó¹ÞÀ½ : accept()
- accept·ÎºÎÅÍ ³Ñ¾î¿Â fd¿¡ Åë½ÅÁغñ : fcntl()
- epoll¿¡ »õ·Î¿î fd µî·Ï : epoll_ctl(..., EPOLL_CTL_ADD, ... )
* ¿¬°á Çϱâ (connect)
- »çÀüÁغñ(»ó´ë¹æ ipÁÖ¼Ò, port¹øÈ£µî) ±×¸®°í ¿¬°á : connect()
- ¿¬°á¼º°øÇϸé connect·ÎºÎÅÍ ³Ñ¾î¿Â fd¿¡ Åë½ÅÁغñ : fcntl()
- epoll¿¡ »õ·Î¿î fd µî·Ï : epoll_ctl(..., EPOLL_CTL_ADD, ... )
* ¿¬°á ²÷±â (connect)
- ¿¬°áÀ» ²÷°í ½Í°Å³ª, ¿¬°áÀÌ ²÷±è »ç°Ç ¹ß»ý ¶Ç´Â ¿¡·¯¹ß»ý : read(), epoll_wait() ¿¡¼ °¨Áö
- epoll¿¡¼ ÇØ´ç fd »èÁ¦ : epoll_ctrl(..., EPOLL_CTL_DEL, ...)
- ¿¬°á ´ÝÀ½ : close()
* epoll Á¾·á : close(), epoll µµ FILEÀ̱⠶§¹®¿¡ ±×³É ´ÝÀ¸¸é µÈ´Ù
* Àбâ (read)
- ÀÐÀ» µ¥ÀÌŸ µµÂøÇßÀ½À» °¨Áö : epoll_wait()
- µ¥ÀÌŸ Àбâ : read()
- Àд µµÁß ¹ß»ýÇÏ´Â ¿¡·¯Ã³¸®, ÇÊ¿ä½Ã ¿¬°á²÷±â
* ¾²±â (write)
- º¸³¾ µ¥ÀÌÅÍ°¡ ¹ß»ýÇÑ °æ¿ì Send Buffer¿¡ ÀÏ´Ü ÀúÀå
- º¸³»µµ µÈ´Ù´Â ½ÅÈ£¸¦ °¨Áö : epoll_wait()
- µ¥ÀÌÅÍ Àü¼Û : write()
- Àü¼Û µµÁß ¹ß»ýÇÏ´Â ¿¡·¯Ã³¸®, ÇÊ¿ä½Ã ¿¬°á²÷±â ȤÀº WOULDBLOCK ó¸®
Âü°í 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 À̺¥Æ®, Áï µ¥ÀÌÅÍ°¡ ¼ö½ÅµÇ¾úÀ»¶§ ÀÐ¾î¼ È¸é¿¡ Ç¥½ÃÇϵµ·Ï Çß´Ù.