eventfd

EVENTFD(2)                 Linux Programmer's Manual                EVENTFD(2)



åå
       eventfd - ã¤ãã³ãéç¥ç¨ã®ãã¡ã¤ã«ãã£ã¹ã¯ãªãã¿ãçæãã

æ¸å¼
       #include <sys/eventfd.h>

       int eventfd(unsigned int initval, int flags);

説æ
       eventfd()  㯠"eventfd ãªãã¸ã§ã¯ã" ãçæããã eventfd
       ãªãã¸ã§ã¯ãã¯ã¦ã¼ã¶ç©ºéã¢ããªã±ã¼ã·ã§ã³ãã¤ãã³ãå¾ã¡åã/éç¥ç¨ã®
       ä»çµã¿ã¨ãã¦ä½¿ããã¨ãã§ãããã¾ããã«ã¼ãã«ãã¦ã¼ã¶ç©ºéã¢ããªã±ã¼ã·ã§ã³ã«
       ã¤ãã³ããéç¥ããããã«ã使ããã¨ãã§ããã ãã®ãªãã¸ã§ã¯ãã«ã¯ãunsigned ã® 64 ãããæ´æ°
       (uint64_t) åã®ã«ã¦ã³ã¿ãå«ã¾ãã¦ããããã®ã«ã¦ã³ã¿ã¯ã«ã¼ãã«ã«ãã管çãããã
       ãã®ã«ã¦ã³ã¿ã¯ initval å¼ãæ°ã§æå®ãããå¤ã§åæåãããã

       以ä¸ã®å¤ã®ããã¤ãããããåä½ã®è«çå (OR) ã§æå®ãããã¨ã§ã eventfd()
       ã®æ¯èããå¤æ´ãããã¨ãã§ããã

       EFD_CLOEXEC (Linux 2.6.27 以é)
              æ°ãããã¡ã¤ã«ãã£ã¹ã¯ãªãã¿ã«å¯¾ã㦠close-on-exec (FD_CLOEXEC)
              ãã©ã°ãã»ããããã ãã®ãã©ã°ãå½¹ã«ç«ã¤çç±ã«ã¤ãã¦ã¯ã open(2)  ã®
              O_CLOEXEC ãã©ã°ã®èª¬æãåç§ã®ãã¨ã

       EFD_NONBLOCK (Linux 2.6.27 以é)
              æ°ããçæããããªã¼ãã³ãã¡ã¤ã«è¨è¿° (open file description) ã®
              O_NONBLOCK ãã¡ã¤ã«ã¹ãã¼ã¿ã¹ãã©ã°ãã»ããããã ãã®ãã©ã°ã使ããã¨ã§ã
              O_NONBLOCK ãã»ããããããã« fcntl(2) ã追å ã§å¼ã³åºãå¿è¦ããªããªãã

       EFD_SEMAPHORE (Linux 2.6.30 以é)
              æ°ãããã¡ã¤ã«ãã£ã¹ã¯ãªãã¿ããã®èªã¿åºãã«ããã¦ãã»ããã©é¢¨ã®åä½ãè¡ãã
              ä¸è¨åç§ã

       ãã¼ã¸ã§ã³ 2.6.26 以åã® Linux ã§ã¯ã flags å¼ãæ°ã¯æªä½¿ç¨ã§ããã0
       ãæå®ããªããã°ãªããªãã

       eventfd()  㯠eventfd
       ãªãã¸ã§ã¯ããåç§ããã®ã«ä½¿ç¨ã§ããæ°ãããã¡ã¤ã«ãã£ã¹ã¯ãªãã¿
       ãè¿ããè¿ããããã¡ã¤ã«ãã£ã¹ã¯ãªãã¿ã«å¯¾ãã¦ã¯ä»¥ä¸ã®æä½ãå®è¡ã§ããã

       read(2)
              read(2) ã¯æåããã¨ã8 ãã¤ãã®æ´æ°ãè¿ãã 渡ããããããã¡ã®å¤§ããã 8
              ãã¤ãæªæºã®å ´åã read(2)  ã¯ã¨ã©ã¼ EINVAL ã§å¤±æããã

              read(2) ãè¿ãå¤ã¯ããã¹ããã¤ããªã¼ããã¤ã¾ã
              ãã®ãã¹ããã·ã³ã«ãããæ´æ°ã®é常ã®ãã¤ããªã¼ãã§ããã

              read(2) ã®åä½ã¯ã eventfd ã«ã¦ã³ã¿ã®ç¾å¨ã®å¤ã 0 以å¤ã§ãããã¨ã
              eventfd ãã¡ã¤ã«ãã£ã¹ã¯ãªãã¿ãä½æããéã« EFD_SEMAPHORE ãã©ã°ã
              æå®ãããããã«ããå¤åããã

              *  EFD_SEMAPHORE ãæå®ããã¦ããããeventfd ã«ã¦ã³ã¿ã 0 以å¤ã®å¤
                 ã®å ´åã read(2) ã¯ã«ã¦ã³ã¿å¤ãæ ¼ç´ãã 8 ãã¤ãã®å¤ãè¿ãã
                 ã«ã¦ã³ã¿å¤ã¯ 0 ã«ãªã»ãããããã

              *  EFD_SEMAPHORE ãæå®ããã¦ã㦠eventfd ã«ã¦ã³ã¿ã 0
                 以å¤ã®å¤ã®å ´åã read(2) ã¯å¤ 1 ã® 8 ãã¤ãå¤ãè¿ããã«ã¦ã³ã¿å¤ã¯
                 1 æ¸ç®ãããã

              *  read(2) ãå¼ã³åºããæç¹ã§ eventfd ã«ã¦ã³ã¿ã 0 ã®å ´åã read(2)
                 ã¯ã«ã¦ã³ã¿ã 0 以å¤ã«ãªãã¾ã§åæ¢ (block) ãã (0
                 以å¤ã«ãªã£ãæç¹ã§ read(2) ã¯ä¸è¨ã§è¿°ã¹ãéãå®è¡ãåéãã)ã
                 ãããã¯ãã¡ã¤ã«ãã£ã¹ã¯ ãªãã¿ãéåæ¢ (nonblocking) ã«è¨‐
                 å®ããã¦ããå ´åã¯ã¨ã©ã¼ EAGAIN㧠失æããã

       write(2)
              write(2)  ã¯ãå¼ãæ°ã®ãããã¡ã§æ¸¡ããã 8
              ãã¤ãã®æ´æ°å¤ãã«ã¦ã³ã¿ã«å ç®ããã ã«ã¦ã³ã¿ã«æ ¼ç´å¯è½ãªæ大å¤ã¯
              unsigned ã® 64 ãããæ´æ°ã®æ大å¤ãã 1 ãå¼ããå¤ (ããªãã¡
              0xfffffffffffffffe) ã§ããã
              å ç®ãè¡ãã¨ã«ã¦ã³ã¿å¤ãæ大å¤ãè¶éããå ´åã«ã¯ã
              ãã®ãã¡ã¤ã«ãã£ã¹ã¯ãªãã¿ã«å¯¾ã㦠read(2)  ãå®è¡ãããã¾ã§ã write(2)
              ã¯åæ¢ (block) ããã ãããã¯ãã¡ã¤ã«ãã£ã¹ã¯ãªãã¿ãéåæ¢ (nonblocking)
              ã«è¨å®ããã¦ããå ´åã¯ã¨ã©ã¼ EAGAIN ã§å¤±æããã

              渡ããããããã¡ã®å¤§ããã 8 ãã¤ãæªæºã®å ´åããããã¯ å¤ 0xffffffffffffffff
              ãæ¸ãè¾¼ããã¨ããå ´åã write(2) ã¯ã¨ã©ã¼ EINVAL ã§å¤±æããã

       poll(2), select(2) (ã¨åæ§ã®æä½)
              è¿ããããã¡ã¤ã«ãã£ã¹ã¯ãªãã¿ã¯ã poll(2)  (epoll(7)  ãåã) ã select(2)
              ããµãã¼ããã¦ããã以ä¸ã®ãããªåä½ãããã

              *  ã«ã¦ã³ã¿ã 0 ãã大ããå¤ã®å ´åã ãã¡ã¤ã«ãã£ã¹ã¯ãªãã¿ã¯èª‐
                 ã¿åºãå¯è½ã¨ãªã (select(2)  ã® readfds å¼ãæ°ã poll(2)  ã®
                 POLLIN ãã©ã°)ã

              *  å°ãªãã¨ãå¤ "1" ããåæ¢ (block) ãä¼´ããã«æ¸ãè¾¼ããå ´åã
                 ãã¡ã¤ã«ãã£ã¹ã¯ãªãã¿ã¯æ¸ãè¾¼ã¿å¯è½ã¨ãªã (select(2)  ã®
                 writefds å¼ãæ°ã poll(2)  ã® POLLOUT ãã©ã°)ã

              *  ã«ã¦ã³ã¿å¤ã®ãªã¼ãã¼ããã¼ãæ¤åºãããå ´åã select(2)
                 ã¯ãã¡ã¤ã«ãã£ã¹ã¯ãªãã¿ã¯èªã¿åºãå¯è½ã¨æ¸ãè¾¼ã¿å¯è½ã®ä¸¡æ¹ãéç¥ãã
                 poll(2)  㯠POLLERR ã¤ãã³ããè¿ãã ä¸è¿°ã®éãã write(2)
                 ã§ã«ã¦ã³ã¿ããªã¼ãã¼ããã¼ãããã¨ã¯æ±ºãã¦ãªãã ããããªããã KAIO
                 ãµãã·ã¹ãã ã«ãã£ã¦ 2^64 åã® eventfd "signal posts" ã
                 å®è¡ãããå ´åã«ã¯ãªã¼ãã¼ããã¼ãèµ·ããå¾ã
                 (çè«çã«ã¯ããå¾ãããå®ç¨çã«ã¯ããå¾ãªã)ã ãªã¼ãã¼ããã¼ãçºçããå ´åã
                 read(2)  㯠uint64_t ã®æå¤§å¤ (ããªãã¡ 0xffffffffffffffff)
                 ãè¿ãã

              eventfd ãã¡ã¤ã«ãã£ã¹ã¯ãªãã¿ã¯ããã以å¤ã®ãã¡ã¤ã«ãã£ã¹ã¯ãªãã¿ å¤é
              API ã§ãã pselect(2) 㨠ppoll(2) ããµãã¼ããã¦ããã

       close(2)
              ãã¡ã¤ã«ãã£ã¹ã¯ãªãã¿ããã以éã¯å¿è¦ãªããªã£ãéã«ã¯ãã¯ãã¼ãºãã¹ãã§ããã
              åã eventfd ãªãã¸ã§ã¯ãã«é¢é£ä»ãããããã¡ã¤ã«ãã£ã¹ã¯ãªãã¿ãå¨ã¦ ã¯ã‐
              ã¼ãºãããã¨ããã®ãªãã¸ã§ã¯ãç¨ã®è³æºãã«ã¼ãã«ã«ãã解æ¾ãããã

       fork(2) ã§çæãããåããã»ã¹ã¯ã eventfd() ã§çæããããã¡ã¤ã«
       ãã£ã¹ã¯ãªãã¿ã®ã³ãã¼ãç¶æ¿ããã è¤è£½ããããã¡ã¤ã«ãã£ã¹ã¯ãªãã¿ã¯å ã eventfd
       ãªãã¸ã§ã¯ãã«é¢é£ä»ããããã close-on-exec ãã©ã°ãè¨å®ããã¦ããªãå ´åã execve(2)
       ã®åå¾ã§ eventfd() ã§çæããããã¡ã¤ã«ãã£ã¹ã¯ãªãã¿ã¯ä¿æãããã

è¿ãå¤
       æåããã¨ã eventfd()  ã¯æ°è¦ã® eventfd ãã¡ã¤ã«ãã£ã¹ã¯ãªãã¿ãè¿ãã
       ã¨ã©ã¼ã®å ´åã-1 ãè¿ãã errno ã«ã¨ã©ã¼ã示ãå¤ãè¨å®ããã

ã¨ã©ã¼
       EINVAL flags ã«ãµãã¼ãããã¦ããªãå¤ãæå®ãããã

       EMFILE ãªã¼ãã³æ¸ã¿ã®ãã¡ã¤ã«ãã£ã¹ã¯ãªãã¿ã®æ°ãããã»ã¹ãããã®ä¸éã« éãã¦ããã

       ENFILE ãªã¼ãã³æ¸ã¿ã®ãã¡ã¤ã«ç·æ°ãã·ã¹ãã å¨ä½ã®ä¸éã«éãã¦ããã

       ENODEV (ã«ã¼ãã«åã®) ç¡å inode ããã¤ã¹ããã¦ã³ãã§ããªãã£ãã

       ENOMEM æ°ãã eventfd ãã¡ã¤ã«ãã£ã¹ã¯ãªãã¿ãçæããã®ã«ååãªã¡ã¢ãªããªãã£ãã

ãã¼ã¸ã§ã³
       eventfd()  ã¯ã«ã¼ãã« 2.6.22 以éã® Linux ã§å©ç¨å¯è½ã§ããã æ£ããåä½ãã
       glibc å´ã®ãµãã¼ãã¯ãã¼ã¸ã§ã³ 2.8 以éã§æä¾ããã¦ããã eventfd2()
       ã·ã¹ãã ã³ã¼ã« (ã注æãåç§) 㯠ã«ã¼ãã« 2.6.27 以éã® Linux
       ã§å©ç¨å¯è½ã§ããã ãã¼ã¸ã§ã³ 2.9 以éã§ã¯ãglibc ã® eventfd()
       ã®ã©ããã¼é¢æ°ã¯ãã«ã¼ãã«ã対å¿ãã¦ããã° eventfd2()  ã·ã¹ãã ã³ã¼ã«ãå©ç¨ããã

æºæ
       eventfd()  㨠eventfd2()  㯠Linux åºæã§ããã

注æ
       ã¢ããªã±ã¼ã·ã§ã³ã¯ããã¤ããã¤ãã³ããéç¥ããããã ãã«ä½¿ç¨ãã¦ãã
       å¨ã¦ã®å ´é¢ã«ããã¦ããã¤ãã®ä»£ããã« eventfd ãã¡ã¤ã«ãã£ã¹ã¯ãªãã¿ã
       使ç¨ãããã¨ãã§ããã eventfd
       ãã¡ã¤ã«ãã£ã¹ã¯ãªãã¿ã使ãæ¹ãããã¤ãã使ãå ´åã«æ¯ã¹ã¦
       ã«ã¼ãã«ã§ã®ãªã¼ããããã¯æ¯ã¹ãã¨ãã£ã¨å°ããããã¡ã¤ã«ãã£ã¹ã¯ãªãã¿ã
       ä¸ã¤ããå¿è¦ã¨ããªã (ãã¤ãã®å ´åã¯äºã¤å¿è¦ã§ãã)ã

       ã«ã¼ãã«åã§ä½¿ç¨ããã¨ãeventfd
       ãã¡ã¤ã«ãã£ã¹ã¯ãªãã¿ã¯ã«ã¼ãã«ç©ºéããã¦ã¼ã¶ç©ºéã¸ã®ããªãã¸æ©è½ãæä¾ãããã¨ãã§ãã
       ä¾ãã° KAIO (kernel AIO)
       ã®ãããªæ©è½ãããããã¡ã¤ã«ãã£ã¹ã¯ãªãã¿ã«ä½ããã®æä½ãå®äºãããã¨ã éç¥ãããã¨ãã§ããã

       eventfd ãã¡ã¤ã«ãã£ã¹ã¯ãªãã¿ã®éè¦ãªç¹ã¯ã eventfd ãã¡ã¤ã«ãã£ã¹ã¯ãªãã¿ã
       select(2), poll(2), epoll(7)
       ã使ã£ã¦ä»ã®ãã¡ã¤ã«ãã£ã¹ã¯ãªãã¿ã¨å¨ãåæ§ã«ç£è¦ã§ããç¹ã§ããã
       ãã®ãã¨ã¯ãã¢ããªã±ã¼ã·ã§ã³ã¯ãå¾æ¥ã® (traditional)ã ãã¡ã¤ã«ã®ç¶æå¤åã¨
       eventfd ã¤ã³ã¿ãã§ã¼ã¹ããµãã¼ãããä»ã®ã«ã¼ãã«æ©æ§ã®ç¶æå¤åãåæã«ç£è¦
       ã§ãããã¨ãæå³ãã (eventfd()  ã¤ã³ã¿ãã§ã¼ã¹ããªãæã«ã¯ããããã®ã«ã¼ãã«æ©æ§ã¯
       select(2), poll(2), epoll(7)  çµç±ã§å¤éãããã¨ã¯ã§ããªãã£ã)ã

   ä¸å±¤ã«ãã Linux ã®ã·ã¹ãã ã³ã¼ã«
       ä¸å±¤ã«ãã Linux ã·ã¹ãã ã³ã¼ã«ã¯äºç¨®é¡ããã eventfd()  ã¨ããã£ã¨æ°ãã
       eventfd2()  ã§ããã eventfd()  㯠flags å¼ãæ°ãå®è£ãã¦ããªãã eventfd2()
       ã§ã¯ä¸è¨ã®å¤ã® flags ãå®è£ããã¦ããã glibc ã®ã©ããã¼é¢æ°ã¯ã eventfd2()
       ãå©ç¨å¯è½ã§ããã°ãããã使ç¨ããã

   glibc ã®è¿½å æ©è½
       GNU C ã©ã¤ãã©ãªã¯ãeventfd ãã¡ã¤ã«ãã£ã¹ã¯ãªãã¿ã®èªã¿åºãã¨æ¸ãè¾¼ã¿ã«
       ãé¢ãã詳細ã®ããã¤ãæ½è±¡åããããã«ãä¸ã¤ã®åã¨ãäºã¤ã®é¢æ°ã追å 㧠å®ç¾©ãã¦ããã

           typedef uint64_t eventfd_t;

           int eventfd_read(int fd, eventfd_t *value);
           int eventfd_write(int fd, eventfd_t value);

       ãããã®é¢æ°ã¯ãeventfd ãã¡ã¤ã«ãã£ã¹ã¯ãªãã¿ã«å¯¾ããèªã¿åºãã¨
       æ¸ãè¾¼ã¿ã®æä½ãå®è¡ããæ£ãããã¤ãæ°ã転éãããå ´åã«ã¯ 0 ãè¿ããããã§ãªãå ´å㯠-1
       ãè¿ãã

ä¾
       以ä¸ã®ããã°ã©ã 㯠eventfd ãã¡ã¤ã«ãã£ã¹ã¯ãªãã¿ãçæãã ãã®å¾ fork
       ãå®è¡ãã¦åããã»ã¹ãçæããã 親ããã»ã¹ãå°ãã®é sleep ããéã«ãåããã»ã¹ã¯ ãã‐
       ã°ã©ã ã®ã³ãã³ãã©ã¤ã³å¼ãæ°ã§æå®ãããæ´æ°(å)ããããã eventfd
       ãã¡ã¤ã«ãã£ã¹ã¯ãªãã¿ã«æ¸ãè¾¼ãã 親ããã»ã¹ã¯ sleep ãå®äºãã㨠eventfd
       ãã¡ã¤ã«ãã£ã¹ã¯ãªãã¿ãã èªã¿åºããè¡ãã

       以ä¸ã«ç¤ºãã·ã§ã«ã»ãã·ã§ã³ã«ãã®ããã°ã©ã ã®ä½¿ãæ¹ã示ãã

           $ ./a.out 1 2 4 7 14
           Child writing 1 to efd
           Child writing 2 to efd
           Child writing 4 to efd
           Child writing 7 to efd
           Child writing 14 to efd
           Child completed write loop
           Parent about to read
           Parent read 28 (0x1c) from efd

   ããã°ã©ã ã®ã½ã¼ã¹

       #include <sys/eventfd.h>
       #include <unistd.h>
       #include <stdlib.h>
       #include <stdio.h>
       #include <stdint.h>             /* Definition of uint64_t */

       #define handle_error(msg) \
           do { perror(msg); exit(EXIT_FAILURE); } while (0)

       int
       main(int argc, char *argv[])
       {
           int efd, j;
           uint64_t u;
           ssize_t s;

           if (argc < 2) {
               fprintf(stderr, "Usage: %s <num>...\n", argv[0]);
               exit(EXIT_FAILURE);
           }

           efd = eventfd(0, 0);
           if (efd == -1)
               handle_error("eventfd");

           switch (fork()) {
           case 0:
               for (j = 1; j < argc; j++) {
                   printf("Child writing %s to efd\n", argv[j]);
                   u = strtoull(argv[j], NULL, 0);
                           /* strtoull() allows various bases */
                   s = write(efd, &u, sizeof(uint64_t));
                   if (s != sizeof(uint64_t))
                       handle_error("write");
               }
               printf("Child completed write loop\n");

               exit(EXIT_SUCCESS);

           default:
               sleep(2);

               printf("Parent about to read\n");
               s = read(efd, &u, sizeof(uint64_t));
               if (s != sizeof(uint64_t))
                   handle_error("read");
               printf("Parent read %llu (0x%llx) from efd\n",
                       (unsigned long long) u, (unsigned long long) u);
               exit(EXIT_SUCCESS);

           case -1:
               handle_error("fork");
           }
       }

é¢é£é ç®
       futex(2), pipe(2), poll(2), read(2), select(2), signalfd(2),
       timerfd_create(2), write(2), epoll(7), sem_overview(7)

ãã®ææ¸ã«ã¤ãã¦
       ãã® man ãã¼ã¸ã¯ Linux man-pages ããã¸ã§ã¯ãã®ãªãªã¼ã¹ 3.51 ã®ä¸é¨
       ã§ãããããã¸ã§ã¯ãã®èª¬æã¨ãã°å ±åã«é¢ããæå ±ã¯
       http://www.kernel.org/doc/man-pages/ ã«æ¸ããã¦ããã



Linux                             2010-08-30                        EVENTFD(2)