Select ´Â Unix Network Programming Ã¥ÀÇ, 6.13 ÀÔÃâ·Â ´ÙÁßÈ­ (309 ÆäÀÌÁö)
   ¿¡ º¸½Ã¸é ÀÚ¼¼È÷ ¼­¼úµÇ¾î ÀÖ½À´Ï´Ù.

   Àü ¸®´ª½º Áß½ÉÀ¸·Î ¼³¸í µå¸®°Ú½À´Ï´Ù.

   ´ÙÀ½Àº select ÇÔ¼öÀÇ man page ÀÔ´Ï´Ù.

NAME
    select, FD_CLR, FD_ISSET, FD_SET, FD_ZERO - synchronous I/O multiplexing

SYNOPSIS
    #include <sys/time.h>
    #include <sys/types.h>
    #include <unistd.h>

    int select(int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
               struct timeval *timeout);

    FD_CLR(int fd, fd_set *set);
    FD_ISSET(int fd, fd_set *set);
    FD_SET(int fd, fd_set *set);
    FD_ZERO(fd_set *set);

   ´ÙÀ½Àº ¿©±â¼­ »ç¿ëµÈ timeval ±¸Á¶Ã¼ÀÇ ¸â¹öµé ÀÔ´Ï´Ù.

   struct timeval {
        time_t          tv_sec;         /* seconds */
        suseconds_t     tv_usec;        /* microseconds */
   };

   time_t ¿Í suseconds_t ´Â long ÇüÀÇ typedef ÀÔ´Ï´Ù.

   ±×¸®°í tv_usec ´Â "¹Ð¸®¼¼ÄÁµå" ´ÜÀ§°¡ ¾Æ´Ñ "¸¶ÀÌÅ©·Î¼¼ÄÁµå" ´ÜÀ§
   ÀÔ´Ï´Ù. (1000000 ¸¶ÀÌÅ©·Î ¼¼ÄÁµå == 1ÃÊ, 1000 ¹Ð¸® ¼¼ÄÁµå == 1ÃÊ,
   1000 ¸¶ÀÌÅ©·Î¼¼ÄÁµå == 1 ¹Ð¸®¼¼ÄÁµå)

   ´ÙÀ½Àº select ÀÇ ÇÔ¼öÀÇ ÀÎÀÚ ¼³¸íÀÔ´Ï´Ù.

   ÆÄÀÏ µð½ºÅ©¸³ÅÍ´Â fd ·Î ÁÙ¿©¼­ ¾²°Ú½À´Ï´Ù. -_-;

   select(int ÃÖ´ë fd °ª, fd_set Àбâ½ÅÈ£, fd_set ¾²±â½ÅÈ£, fd_set ¿¹¿Ü½ÅÈ£,
          struct timeval ½¯ ½Ã°£)

   ÃÖ´ë fd °ªÀº (À©µµ¿ì¿¡¼± À̹æ¹ý ¾ÈÅëÇÔ -_-) °Á ¼ÒÄÏÀº integer ÇüÀÌÁÒ?
   ±×¸®°í ±× ¼ÒÄÏÁß¿¡¼­ °¡Àå Å« °ªÀÌ ÃÖ´ë fd °ªÀÔ´Ï´Ù.

   Ã¥¿¡´Â ÀÌ·¸°Ô ¼³¸íµÇ¾î ÀÖ½À´Ï´Ù.

   "select¿¡ ´ëÇÑ ¿äûÀº ÁýÇÕ {1,4,5} ¿¡ ÀÖ´Â È­ÀÏ ÁöÁ¤¹øÈ£°¡ ÀÐÀ» Áغñ°¡
    µÇ¾î ÀÖ´ÂÁö ¶Ç´Â ÁýÇÕ {2,7}¿¡ ÀÖ´Â È­ÀÏ ÁöÁ¤¹øÈ£°¡ Ãâ·ÂÇÒ Áغñ°¡ µÇ¾î
    ÀÖ´ÂÁö, ¶Ç´Â ÁýÇÕ {1,4}¿¡ ÀÖ´Â È­ÀÏ ÁöÁ¤ ¹øÈ£°¡ ¹Ì°á ¿¹¿ÜÁ¶°Ç (exeptional
    condition pending) À» °®°í ÀÖ´ÂÁö¸¦ ¿ì¸®¿¡°Ô ¸»ÇØÁÙ ¼ö ÀÖ´Ù. Ãß°¡ÀûÀ¸·Î
    ¿ì¸®´Â ¾Ë¸ÍÀÌ¿¡°Ô ¾Æ·¡¿Í °°Àº »çÇ×µéÀ» ¿äûÇÒ ¼ö ÀÖ´Ù.

    Çؼ®: (ÀÌÃ¥Àº ¿ø¼­´Â ±×³É ±×·±µ¥ ÇØ¼®º»ÀÌ ¿ÏÀü ¾û¸ÁÀÓ ÇªÇÏÇÏ)
          ¿ì¼± ¾Ë¸ÍÀÌ´Â Ä¿³Î(Kernel) À» ¶æÇÕ´Ï´Ù. ÇѸ¶µð·Î select ÇÔ¼ö¸¦
          È£ÃâÇØ ÇØ´ç fd (¼ÒÄÏ Æ÷ÇÔ) ¿¡¼­ Àоî¿Ã ¼ö ÀÖ³ª Ãâ·ÂÇÒ ¼öÀÖ³ª
          ¿¹¿Ü°¡ Àִ°¡¸¦ ¾Ë¾Æ¿Ã ¼ö ÀÖ´Ù´Â °ÅÁÒ. -.-;
         

    -------------
    Ã¹¹øÂ° »ç¿ë¹ý
    -------------
    o ÁöÁ¤¹øÈ£µéÀ» Á¶»çÇÑ ÈÄ¿¡ Áï½Ã µ¹·ÁÁֽÿÀ. À̰ÍÀº ÀÀ´äÁ¶»çÀÌ´Ù. À̰ÍÀ»
      À§ÇØ timeout µ¶¸³º¯¼ö´Â timeval ±¸Á¶¸¦ °¡¸®Å°°í ÀÖ¾î¾ß ÇÑ´Ù. ½Ã°£
      ÃøÁ¤ÀÇ °ªÀº 0 À̾î¾ß ÇÑ´Ù. (½Ã°£ ÃøÁ¤±âÀÇ °ªÀº ±¸Á¶¿¡¼­ ±ÔÁ¤ÇÑ seconds
      ¶Ç´Â microseconds)

    - ÇØ¼®:

      ¿©±â¼­ 'ÁöÁ¤¹øÈ£µé'Àº ÃÖ´ë fd °ªÀÇ ¾Æ·¡¹øÈ£¸¦ °¡Áø fd °¡ µÇ°Ú½À´Ï´Ù.
      ±×¸®°í ½Ã°£ ÃøÁ¤ÀÇ °ªÀº 0 À̾î¾ß ÇÑ´Ù À̸»Àº select() ÇÔ¼öÀÇ ¸Ç
      ¸¶Áö¸· ÀÎÀÚ struct timeval À» 0 À¸·Î ¸ðµÎ ¸¸µé¾î¼­ ³Ö¾î¾ß ¿øÇÏ´Â
      ¹æÇâÀ¸·Î ¸¸µé¾î Áø´Ù´Â °Ì´Ï´Ù.
 
    - ÀÌ·¸°Ô ÇÏ·Á¸é?

      fd_set input, output, exc;
      struct timeval nulltime;

      nulltime.tv_sec  = 0;
      nulltime.tv_usec = 0;

      FD_ZERO(&input);
      FD_ZERO(&output);
      FD_ZERO(&exc);

      FD_SET(Á¢¼ÓÀ» ¹Þ°í ÀÖ´Â fd, &input);
      // Á¢¼ÓÀ» ¹Þ°í ÀÖ´Â fd ¶õ ¼­¹ö°¡ ¶ç¿öÁø Æ÷Æ®¿¡ ¹°¸° ¼ÒÄÏÀÇ ¹øÈ£¸¦
      // ¶æÇÕ´Ï´Ù.

      // ¸ðµç µð½ºÅ©¸³ÅÍ¿¡ input, output, exc ¸¦ ¼ÂÆÃÇÑ´Ù.
      ·çÇÁ {
         FD_SET(fd, &input);
         FD_SET(fd, &output);
         FD_SET(fd, &exc);
      }

      select(ÃÖ´ë fd °ª + 1, &input, &output, &exc, &nulltime);

      // È£Ãâ ÈÄ¿¡´Â ¸ðµç µð½ºÅ©¸³ÅͰ¡ Àбâ/¾²±â/¿¹¿ÜÀÎÁö °Ë»ç

      // ¿¹¿Ü¸¦ °Ë»ç
      ·çÇÁ {
         if (FD_ISSET(À̹øfd, &exc))
             ¿¹¿Ü ¹ß»ý ¼ÒÄÏÀ» ²÷¾îÁØ´Ù.
      }

      // Àб⠰¡´É °Ë»ç
      ·çÇÁ {
         if (FD_ISSET(À̹øfd, &input))
             Àб⠰¡´É ¼ÒÄÏ¿¡¼­ ÀоîÁØ´Ù.
      }

      // ¾²±â °¡´É °Ë»ç
      ·çÇÁ {
         if (FD_ISSET(À̹øfd, &output))
             ¾²±â °¡´É ¼ÒÄÏ¿¡ ¾µ ³»¿ëÀÌ ÀÖ´Ù¸é ½áÁØ´Ù.
      }

      À§¿Í °°Àº ¹æ½ÄÀ¸·Î »ç¿ëÇÏ¸é µÇ°Ú½À´Ï´Ù. À©µµ¿ì¿¡¼± ¸Þ¼¼Áö¸¦ ¹Þ¾Æ
      Ã³¸®ÇÑ´Ù´Â ºÐµéµµ °è½Ã´Âµ¥ ½áº¸Áö ¾Ê¾Æ µÑÁß ¾î´À °ÍÀÌ ¼Óµµ¸é¿¡¼­
      ³ªÀ»Áö´Â Àß ¸ð¸£°Ú½À´Ï´Ù. (󸮴 ÈξÀ ÆíÇϰڱº. -_-)

    - ÇÊ¿äÇÑ °÷Àº?

    Á¦ÀÏ Áß¿ä ºÎºÐÀ̶ó ÇÒ ¼ö ÀÖ´Â ¿©·¯ ¼ÒĹ¿¡¼­ÀÇ ÀбⰡ´É/¾²±â°¡´É/¿¹¿Ü¸¦
    ¾ò¾î¿Ã ¶§. ÇѸ¶µð·Î ¼­¹öÀÇ ÁßÃßÀûÀÎ ¿ªÇÒÀ» ÇÒ ¼ö ÀÖ°Ô ÇÒ ¶§.


    -------------
    µÎ¹øÂ° »ç¿ë¹ý
    -------------
    o ÁöÁ¤µÈ ÁöÁ¤¹øÈ£µéÁßÀÇ Çϳª°¡ I/O Áغñ°¡ µÉ ¶§ µ¹·Á ÁÖµÇ °íÁ¤µÈ ½Ã°£
      ÀÌ»óÀ» ±â´Ù¸®Áö ¸¶½Ã¿À.  À̰ÍÀ» À§ÇØ timeout µ¶¸³º¯¼ö´Â timeval ±¸Á¶¸¦
      °¡¸®Å°°í ÀÖ¾î¾ß Çϸç ÀÌ °ªÀº ±â´Ù¸± ½Ã°£À̸ç 0 ÀÌ ¾Æ´Ï¾î¾ß ÇÑ´Ù.
      (½Ã°£ ÃøÁ¤±âÀÇ °ªÀº ±¸Á¶¿¡¼­ ±ÔÁ¤µÈ seconds ¶Ç´Â microseconds)
      
    - ÇØ¼®:
      (ÀÌ¹Ì ¼³¸íÇÑ ºÎºÐÀ» °Ç³Ê ¶Ùµµ·Ï ÇϰڽÀ´Ï´Ù.)     

      º°°Å ¾ø½À´Ï´Ù. ±×³É timeval ±¸Á¶³»¿¡ ÀÖ´Â ½Ã°£¸¸Å­ ÇÁ·Î¼¼½º¸¦
      ÀáÀç¿î´Ù. ÀÔ´Ï´Ù. -_-;

    - ÀÌ·¸°Ô ÇÏ·Á¸é?

      struct timeval timeout;

      timeout.tv_sec  = 0;
      timeout.tv_usec = 1000;

      select(0, (fd_set *) 0, (fd_set *) 0, (fd_set *) 0, &timeout);

      °á°ú: 1 ¹Ð¸® ¼¼ÄÁµå (1000 ¸¶ÀÌÅ©·Î ¼¼ÄÁµå) ÇÁ·Î¼¼½º¸¦ ÀáÀç¿ó´Ï´Ù.

    - ÇÊ¿äÇÑ °÷Àº?
      ÇÁ·¹ÀÓ µ¿±âÈ­¿¡ ¾µ ¼ö ÀÖ°Ú½À´Ï´Ù. sleep °°Àº ¹«½ÄÇϰí Á¶±Ý¹Û¿¡ ¸ø½¬´Â
      ÇÔ¼öº¸´Ü nanosleep() À̳ª, usleep() ȤÀº ÀÌ select() ÇÔ¼ö¸¦ ÀÌ¿ëÇØ
      ½¬°Ô ÇÏ´Â ¹æ¹ýµµ ±¦ÂúÀº ¹æ¹ý. À©µµ¿ì¿¡¼± Sleep() ÇÔ¼ö·Î ´ÙÀ½°ú °°Àº
      ¹æ¹ýÀ¸·Î ÀáÀç¿ï ¼ö ÀÖ°Ú½À´Ï´Ù.

      Sleep(timeout.tv_sec * 1000 + timeout.tv_usec / 1000);


    -------------
    ¼¼¹øÂ° »ç¿ë¹ý
    -------------
    o ÁöÁ¤µÈ ÁöÁ¤¹øÈ£µéÁßÀÇ Çϳª°¡ I/O Áغñ°¡ µÉ¶§±îÁö ¹«Á¶°Ç ±â´Ù¸®´Ù
      Áغñ°¡ µÇ¾úÀ»¶§ µ¹·Á ÁֽÿÀ. À̰ÍÀ» À§ÇØ timeout µ¶¸³º¯¼ö´Â NULL À̾î¾ß
      ÇÑ´Ù. ÀÌ·¯ÇÑ ±â´Ù¸²Àº ½ÅÈ£¿¡ ÀÇÇØ ÀϽà Áß´ÜµÉ ¼ö ÀÖ´Ù.

    - ÇØ¼®:
      ÃÖ´ë fd °ªº¸´Ù ÀûÀº °ªÀ» °¡Áø fd µéÀÇ ÀÔ·Â/Ãâ·Â/¿¹¿Ü°¡ »ý±æ ¶§ ±îÁö
      ÇÁ·Î¼¼½º¸¦ ÀáÀç¿ì´Ù »ý±â¸é ÇÔ¼ö¸¦ ¸®ÅÏ ½Ãŵ´Ï´Ù. ÀÌ·¸°Ô ÇÏ·Á¸é select()

      ÇÔ¼öÀÇ ¸¶Áö¸· ÀÎÀÚ´Â NULL ·Î ÁÖ¾î¾ß ÇÕ´Ï´Ù. ±×¸®°í ½Ã±×³Î¿¡ ÀÇÇØ
      ¸®Å쵃 ¼öµµ ÀÖ½À´Ï´Ù.

    - ÀÌ·¸°Ô ÇÏ·Á¸é?
 
      fd_set input;

      select(ÃÖ´ë fd °ª + 1, &input, (fd_set *) 0, (fd_set *) 0, NULL);

      Çϸé ÇØ´ç fdµé¿¡¼­ ¹º°¡ ¹ß»ýÇØ¼­ ¶Ç´Â ½Ã±×³ÎÀÌ ÇÁ·Î¼¼½º¸¦ ±ú¿ï ¶§
      ±îÁö ÀáÀ» Àâ´Ï´Ù. -_-;

    - ÇÊ¿äÇÑ °÷Àº?
      Á¢¼ÓµÈ »ç¶÷µéÀÌ ¾øÀ» ¶§ Á¢¼ÓµÈ »ç¶÷µéÀÌ ¾øÀ» °æ¿ì ¼­¹ö°¡ ÀÏÀ» ÇÒ
      Çʿ䰡 ¾øÀ» ¶§, Àá½Ã ÀáÀç¿ì±â À§ÇØ ¾¹´Ï´Ù. (sleep ¸ðµå¶ó°íµµ ÇÕ´Ï´Ù.)

 

    ±×·³ µµ¿òÀÌ µÇ¼Ì±æ ºô¸ç. À̸¸

-ºñ¿±