Á¤È£ÇüÀÌ Á¤¸®ÇسõÀº °Í ÆÛ¿È.
Multiplexing API #
- select, poll, epoll, kqueue µîÀÇ mechanism´Â ¿©·¯ event source·ÎºÎÅÍ ¹ß»ýÇÏ´Â event¸¦
multiplexing ÇØÁÖ´Â ¿ªÇÒÀ» ÇÑ´Ù.
Reactor patternÀ» ±¸ÇöÇϴµ¥ »ç¿ëµÈ´Ù.
- ÇÁ·Î±×·¡¸Ó°¡ event sourceµéÀ» API¿¡ Á¦°øÇϸé, API´Â event°¡ ¹ß»ýÇÒ ¶§±îÁö ÇÁ·Î¼¼½º¸¦ sleep ½ÃÄ×´Ù°¡, event°¡ ¹ß»ýÇϸé, ÇÁ·Î±×·¡¸Ó¿¡°Ô ¹ß»ýÇÑ event¿¡ ´ëÇÑ Á¤º¸¸¦ µ¹·ÁÁØ´Ù.
- event source¸¦ ¸í½ÃÇÏ´Â ¹æ½Ä¿¡ µû¶ó, µÎ°¡Áö API ÇüÅ°¡ ÀÖ´Ù.
- select, poll: ¸ðµç event source¸¦ wait API¸¦ È£ÃâÇÒ ¶§¸¶´Ù ³Ñ°ÜÁØ´Ù.
- select()
int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
struct timeval *timeout);
- poll()
int poll(struct pollfd *fds, unsigned int nfds, int timeout);
- epoll, kqueue: event sourceµéÀÇ ÁýÇÕÀ» Ç¥ÇöÇÏ´Â kernel °´Ã¼¸¦ °¡Áö°í ÀÖ¾î¼, ÀÌ·¯ÇÑ °´Ã¼¸¦ »ý¼ºÇÏ´Â API, ÀÌ ÁýÇÕ¿¡ event source¸¦ Ãß°¡/»èÁ¦/º¯°æÇÏ´Â API, ±×¸®°í ƯÁ¤ ÁýÇÕ¿¡ ´ëÇØ event¸¦ ±â´Ù¸®´Â API¸¦ °¡Áø´Ù.
- epoll_create(), epoll_ctl(), epoll_wait()
int epoll_create(int size);
int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);
int epoll_wait(int epfd, struct epoll_event * events, int maxevents, int timeout);
- kqueue(), kevent()
int kqueue(void);
// kevent´Â event sourceÀÇ Ãß°¡/»èÁ¦/º¯°æ°ú event¸¦ ±â´Ù¸®´Â ¿ªÇÒ µÎ°¡Áö¸¦ ÇÑ´Ù.
int kevent(int kq, const struct kevent *changelist, int nchanges,
struct kevent *eventlist, int nevents,
const struct timespec *timeout);
Changing event sources #
single-threaded app #
- wait operationÀ» ÇÏ´Â µ¿¾È event source¸¦ º¯°æÇÏ´Â ¹æ¹ýÀÌ ¾øÀ¸¹Ç·Î, wait operationÀÌ ÇÊ¿äÇÒ ¶§¸¶´Ù, ºüÁ®³ª¿Í¾ßÇÑ´Ù.
while (...)
{
// build event source set
...
// wait event
select(...);
}
multi-threaded app #
- wait operation µµÁß¿¡, ´Ù¸¥ thread¿¡¼ event source¸¦ º¯°æÇÒ °¡´É¼ºÀÌ ÀÖ´Ù.
select, poll #
- wait API¸¦ ÅëÇØ ³Ñ°ÜÁö´Â parameter¸¦ ÅëÇؼ¸¸ event source¸¦ º¯°æÇÒ ¼ö ÀÖÀ¸¹Ç·Î, single-threaded app°ú °°Àº ¹æ½ÄÀ» »ç¿ëÇÏ¿©¾ß ÇÑ´Ù. µû¶ó¼, wait operation ÁßÀ̶ó¸é, ÇØ´ç operationÀ» ÁßÁöÇϵµ·Ï ÇÏ´Â ¹æ¹ýÀÌ ÇÊ¿äÇÏ´Ù.
- signalÀ» ÀÌ¿ëÇÏ¿© ÁßÁöÇÏ´Â ¹æ¹ý: POSIX signalÀº system callÀ» ÁߴܽÃų ¼ö ÀÖ´Ù. ÇÏÁö¸¸, wait op ¹Ù±ù¿¡ ÀÖÀ» ¶§, signalÀ» ¹è´ÞÇÑ´Ù¸é, signalÀº ¾Æ¹«·± È¿°ú¸¦ °¡ÁöÁö ¸øÇϹǷÎ, ´ÙÀ½ »çÇ×À» °í·ÁÇؾßÇÑ´Ù.
- wait op ¹Ù±ù¿¡¼ signalÀ» blockÇÒ °æ¿ì, race conditionÀÌ ¹ß»ýÇÑ´Ù.
// block signal
...
while (...)
{
// build event source set
...
// unblock signal
...
// signal can be delivered at this point!!!
// wait event
select(...);
// block signal
...
}
- unblock-wait-blockÀ» atomicÇÏ°Ô ¼öÇàÇÏ´Â pselect()¸¦ »ç¿ëÇÒ ¼ö ÀÖ´Ù.
// block signal
...
while (...)
{
// build event source set
...
// wait event
pselect(...);
}
- linux platform¿¡¼´Â pselect()¸¦ À§ÇÑ system call()ÀÌ ¾øÀ¸¹Ç·Î, pselect()¸¦ atomicÇÏ°Ô ±¸ÇöÇÒ ¼ö ¾ø´Ù. ÇöÀç linux¿¡¼´Â GNU libc°¡ pselect()¸¦ ±¸ÇöÇÏ°í ÀÖ´Ù.
- wait API¿¡ timeoutÀ» ¼³Á¤ÇÏ¿© ÁÖ±âÀûÀ¸·Î event source setÀ» ¼öÁ¤ÇÒ ¼ö ÀÖÁö¸¸, event 󸮿¡ timeout ±â°£¸¸ÅÀÇ delay°¡ ¹ß»ýÇÒ °¡´É¼ºÀÌ ÀÖ´Ù.
- Ãß°¡ÀûÀÎ event source¸¦ µî·ÏÇÏ¿© ÁßÁöÇÏ´Â ¹æ¹ý: Á¦¾î °¡´ÉÇÑ event source¸¦ Ç×»ó µî·ÏÇÏ¿©, ÇÊ¿äÇÒ ¶§ ÀÎÀ§ÀûÀ¸·Î event¸¦ ¹ß»ý½ÃÄÑ, wait operationÀ» ÁߴܽÃų ¼ö ÀÖ´Ù.
epoll, kqueue #
- epoll, kqueue: event source ÁýÇÕÀ» º¯°æÇÏ´Â API¸¦ µû·Î °¡Áö¹Ç·Î, À̸¦ »ç¿ëÇÑ´Ù.
- kqueueÀÇ °æ¿ì¿¡´Â, kevent()ÀÇ eventlist¿Í nevents parameter¸¦ »ç¿ëÇÏÁö ¾Ê°í (nevents = 0), È£ÃâÇÏ¿©, wait opÀ» ¼öÇàÇÏÁö ¾Ê°í, event source ÁýÇÕ¸¸À» º¯°æÇÒ ¼ö ÀÖ´Ù.