<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          epoll 能監(jiān)聽普通文件嗎?

          共 4706字,需瀏覽 10分鐘

           ·

          2021-05-11 08:29

          epoll 是 Linux 系統(tǒng)中常用的多路復(fù)用 I/O 組件,一般用于監(jiān)聽 socket 是否能夠進(jìn)行 I/O 操作。那么,epoll 能監(jiān)聽普通文件嗎?

          我們先通過下面的例子來驗(yàn)證一下,epoll 能不能監(jiān)聽普通文件:

           1#include <stdio.h>
          2#include <sys/epoll.h>
          3#include <fcntl.h>
          4
          5int main()
          6
          {
          7   int epfd, fd;
          8   struct epoll_event evevents[2];
          9   int result;
          10
          11   epfd = epoll_create(10);
          12   if (epfd < 0) {
          13       perror("epoll_create()");
          14       return -1;
          15  }
          16
          17   fd = open("./test.txt", O_RDONLY | O_CREAT);
          18   if (fd < 0) {
          19       perror("open()");
          20       return -1;
          21  }
          22
          23   ev.events = EPOLLIN;
          24
          25   result = epoll_ctl(epfd, EPOLL_CTL_ADD, fd, &ev);
          26   if (result < 0) {
          27       perror("epoll_ctl()");
          28       return -1;
          29  }
          30
          31   epoll_wait(epfd, events, 2-1);
          32
          33   return 0;
          34}

          編譯并且運(yùn)行,結(jié)果如下:

          [vagrant@localhost epoll]$ gcc epoll.c -o epoll
          [vagrant@localhost epoll]$ ./epoll
          epoll_ctl(): Operation not permitted

          可以看到上面的運(yùn)行結(jié)果報(bào) Operation not permitted 的錯(cuò)誤,這說明 epoll 是不能監(jiān)聽普通文件的,為什么呢?

          尋根究底

          我們應(yīng)該對(duì)追尋真相抱著熱衷的態(tài)度,所以必須找出 epoll 不能監(jiān)聽普通文件的原因。

          因?yàn)樵谏厦娴睦又校?epoll_ctl 函數(shù)報(bào)的錯(cuò),所以我們首先應(yīng)該從 epoll_ctl 的源碼入手,如下:

           1SYSCALL_DEFINE4(epoll_ctl, int, epfd, int, op, int, fd,
          2               struct epoll_event __user *, event)
          3{
          4   int error;
          5   struct file *file, *tfile;
          6
          7  ...
          8
          9   error = -EBADF;
          10   file = fget(epfd);  // epoll 句柄對(duì)應(yīng)的文件對(duì)象
          11   if (!file)
          12       goto error_return;
          13
          14   tfile = fget(fd);   // 被監(jiān)聽的文件句柄對(duì)應(yīng)的文件對(duì)象
          15   if (!tfile)
          16       goto error_fput;
          17
          18   error = -EPERM; // Operation not permitted 錯(cuò)誤號(hào)
          19   if (!tfile->f_op || !tfile->f_op->poll)
          20       goto error_tgt_fput;
          21
          22  ...
          23
          24error_tgt_fput:
          25   fput(tfile);
          26error_fput:
          27   fput(file);
          28error_return:
          29
          30   return error;
          31}

          從上面代碼可以看出,當(dāng)被監(jiān)聽的文件沒有提供 poll 接口時(shí),就會(huì)返回 EPERM 的錯(cuò)誤,這個(gè)錯(cuò)誤就是 Operation not permitted 的錯(cuò)誤號(hào)。

          所以,出現(xiàn) Operation not permitted 的原因就是:被監(jiān)聽的文件沒有提供 poll 接口。

          由于我們的文件系統(tǒng)是 ext4,所以我們來看看 ext4 文件系統(tǒng)中的文件是否提供了 poll 接口(位于文件 /fs/ext4/file.c 中):

           1const struct file_operations ext4_file_operations = {
          2  .llseek         = generic_file_llseek,
          3  .read           = do_sync_read,
          4  .write          = do_sync_write,
          5  .aio_read       = generic_file_aio_read,
          6  .aio_write      = ext4_file_write,
          7  .unlocked_ioctl = ext4_ioctl,
          8  .mmap           = ext4_file_mmap,
          9  .open           = ext4_file_open,
          10  .release        = ext4_release_file,
          11  .fsync          = ext4_sync_file,
          12  .splice_read    = generic_file_splice_read,
          13  .splice_write   = generic_file_splice_write,
          14};

          ext4 文件的文件操作函數(shù)集被設(shè)置為 ext4_file_operations(也說就是:file->f_op = ext4_file_operations),從上面代碼可以看出,ext4_file_operations 并沒有提供 poll 接口。所以,當(dāng)調(diào)用 epoll_ctl 把文件添加到 epoll 中進(jìn)行監(jiān)聽時(shí),就會(huì)返回 Operation not permitted 的錯(cuò)誤。

          從上面的分析可知,當(dāng)文件系統(tǒng)提供 poll 接口時(shí),就可以把文件添加到 epoll 中進(jìn)行監(jiān)聽。


          瀏覽 32
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  就爱日五月天 | 成人网久久精品无码AV | 亚洲IV秘 一区二区三区 | 丁香花五月 | 操日韩 |