Á¤È£ÇüÀÌ Á¤¸®ÇسõÀº °Í ÆÛ¿È. == Multiplexing API == * select, poll, epoll, kqueue µîÀÇ mechanism´Â ¿©·¯ event source·ÎºÎÅÍ ¹ß»ýÇÏ´Â event¸¦ [http://en.wikipedia.org/wiki/Multiplexing multiplexing] ÇØÁÖ´Â ¿ªÇÒÀ» ÇÑ´Ù. * [http://www.cs.wustl.edu/~schmidt/PDF/reactor-siemens.pdf Reactor pattern]À» ±¸ÇöÇϴµ¥ »ç¿ëµÈ´Ù. * ÇÁ·Î±×·¡¸Ó°¡ event sourceµéÀ» API¿¡ Á¦°øÇϸé, API´Â event°¡ ¹ß»ýÇÒ ¶§±îÁö ÇÁ·Î¼¼½º¸¦ sleep ½ÃÄ×´Ù°¡, event°¡ ¹ß»ýÇϸé, ÇÁ·Î±×·¡¸Ó¿¡°Ô ¹ß»ýÇÑ event¿¡ ´ëÇÑ Á¤º¸¸¦ µ¹·ÁÁØ´Ù. * event source¸¦ ¸í½ÃÇÏ´Â ¹æ½Ä¿¡ µû¶ó, µÎ°¡Áö API ÇüÅ°¡ ÀÖ´Ù. 1. select, poll: ¸ðµç event source¸¦ wait API¸¦ È£ÃâÇÒ ¶§¸¶´Ù ³Ñ°ÜÁØ´Ù. * select() {{{#!vim cpp int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout); }}} * poll() {{{#!vim cpp int poll(struct pollfd *fds, unsigned int nfds, int timeout); }}} 1. epoll, kqueue: event sourceµéÀÇ ÁýÇÕÀ» Ç¥ÇöÇÏ´Â kernel °´Ã¼¸¦ °¡Áö°í À־, ÀÌ·¯ÇÑ °´Ã¼¸¦ »ý¼ºÇÏ´Â API, ÀÌ ÁýÇÕ¿¡ event source¸¦ Ãß°¡/»èÁ¦/º¯°æÇÏ´Â API, ±×¸®°í ƯÁ¤ ÁýÇÕ¿¡ ´ëÇØ event¸¦ ±â´Ù¸®´Â API¸¦ °¡Áø´Ù. * epoll_create(), epoll_ctl(), epoll_wait() {{{#!vim cpp 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() {{{#!vim cpp 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ÀÌ ÇÊ¿äÇÒ ¶§¸¶´Ù, ºüÁ®³ª¿Í¾ßÇÑ´Ù. {{{#!vim cpp 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À» ÁßÁöÇϵµ·Ï ÇÏ´Â ¹æ¹ýÀÌ ÇÊ¿ä'''ÇÏ´Ù. 1. signalÀ» ÀÌ¿ëÇÏ¿© ÁßÁöÇÏ´Â ¹æ¹ý: POSIX signalÀº system callÀ» ÁߴܽÃų ¼ö ÀÖ´Ù. ÇÏÁö¸¸, wait op ¹Ù±ù¿¡ ÀÖÀ» ¶§, signalÀ» ¹è´ÞÇÑ´Ù¸é, signalÀº ¾Æ¹«·± È¿°ú¸¦ °¡ÁöÁö ¸øÇϹǷÎ, ´ÙÀ½ »çÇ×À» °í·ÁÇؾßÇÑ´Ù. * wait op ¹Ù±ù¿¡¼­ signalÀ» blockÇÒ °æ¿ì, race conditionÀÌ ¹ß»ýÇÑ´Ù. {{{#!vim cpp // 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()¸¦ »ç¿ëÇÒ ¼ö ÀÖ´Ù. {{{#!vim cpp // 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°¡ ¹ß»ýÇÒ °¡´É¼ºÀÌ ÀÖ´Ù. 1. Ãß°¡ÀûÀÎ 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 ÁýÇÕ¸¸À» º¯°æÇÒ ¼ö ÀÖ´Ù.