学习
实践
活动
工具
TVP
写文章
专栏首页Linux内核那些事epoll 能监听普通文件吗?

epoll 能监听普通文件吗?

epoll 是 Linux 系统中常用的多路复用 I/O 组件,一般用于监听 socket 是否能够进行 I/O 操作。那么,epoll 能监听普通文件吗?

我们先通过下面的例子来验证一下,epoll 能不能监听普通文件:

#include <stdio.h>
#include <sys/epoll.h>
#include <fcntl.h>

int main()
{
   int epfd, fd;
   struct epoll_event ev, events[2];
   int result;

   epfd = epoll_create(10);
   if (epfd < 0) {
       perror("epoll_create()");
       return -1;
  }

   fd = open("./test.txt", O_RDONLY | O_CREAT);
   if (fd < 0) {
       perror("open()");
       return -1;
  }

   ev.events = EPOLLIN;

   result = epoll_ctl(epfd, EPOLL_CTL_ADD, fd, &ev);
   if (result < 0) {
       perror("epoll_ctl()");
       return -1;
  }

   epoll_wait(epfd, events, 2, -1);

   return 0;
}

编译并且运行,结果如下:

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

可以看到上面的运行结果报 Operation not permitted 的错误,这说明 epoll 是不能监听普通文件的,为什么呢?

寻根究底

我们应该对追寻真相抱着热衷的态度,所以必须找出 epoll 不能监听普通文件的原因。

因为在上面的例子中,是 epoll_ctl 函数报的错,所以我们首先应该从 epoll_ctl 的源码入手,如下:

SYSCALL_DEFINE4(epoll_ctl, int, epfd, int, op, int, fd,
               struct epoll_event __user *, event)
{
   int error;
   struct file *file, *tfile;

  ...

   error = -EBADF;
   file = fget(epfd);  // epoll 句柄对应的文件对象
   if (!file)
       goto error_return;

   tfile = fget(fd);   // 被监听的文件句柄对应的文件对象
   if (!tfile)
       goto error_fput;

   error = -EPERM; // Operation not permitted 错误号
   if (!tfile->f_op || !tfile->f_op->poll)
       goto error_tgt_fput;

  ...

error_tgt_fput:
   fput(tfile);
error_fput:
   fput(file);
error_return:

   return error;
}

从上面代码可以看出,当被监听的文件没有提供 poll 接口时,就会返回 EPERM 的错误,这个错误就是 Operation not permitted 的错误号。

所以,出现 Operation not permitted 的原因就是:被监听的文件没有提供 poll 接口。

由于我们的文件系统是 ext4,所以我们来看看 ext4 文件系统中的文件是否提供了 poll 接口(位于文件 /fs/ext4/file.c 中):

const struct file_operations ext4_file_operations = {
  .llseek         = generic_file_llseek,
  .read           = do_sync_read,
  .write          = do_sync_write,
  .aio_read       = generic_file_aio_read,
  .aio_write      = ext4_file_write,
  .unlocked_ioctl = ext4_ioctl,
  .mmap           = ext4_file_mmap,
  .open           = ext4_file_open,
  .release        = ext4_release_file,
  .fsync          = ext4_sync_file,
  .splice_read    = generic_file_splice_read,
  .splice_write   = generic_file_splice_write,
};

ext4 文件的文件操作函数集被设置为 ext4_file_operations(也说就是:file->f_op = ext4_file_operations),从上面代码可以看出,ext4_file_operations 并没有提供 poll 接口。所以,当调用 epoll_ctl 把文件添加到 epoll 中进行监听时,就会返回 Operation not permitted 的错误。

从上面的分析可知,当文件系统提供 poll 接口时,就可以把文件添加到 epoll 中进行监听。

文章分享自微信公众号:
Linux内核那些事

本文参与 腾讯云自媒体分享计划 ,欢迎热爱写作的你一起参与!

作者:songsong001
原始发表时间:2021-05-11
如有侵权,请联系 cloudcommunity@tencent.com 删除。
登录 后参与评论
0 条评论

相关文章

  • [windows]roaming文件夹能删除吗?

    如果你是因为C盘不够了,那就去找下C盘中是否有大容量的文件,或者roaming中的大容量文件,可以通过CMD命令简单的查看到,比如下面这么干:

    djc8小码农
  • 入行8年的普通程序员,能赚100万吗?

    今天我是突然刷到这一类型的文章——教你程序员快速赚100万。我看到了如下的文章,我突然自闭了,为了验证事实,我采访了我4个朋友。

    黄啊码
  • ssh配置config文件命令_config文件能删除吗

    在使用ssh连接服务器时,经常要输入一些不同的主机地址和密码,使用config文件可以很好的解决这个问题。

    全栈程序员站长
  • [答疑]Rhapsody的文件能转到EA里面吗

    以前自己用rhapsody做了一些图,现在离开单位没得这个软件用了,我想把现在的文件转到ea里面,可行吗?

    用户6288414
  • linux 误删文件恢复_centos删除的文件能恢复吗

    本文参考http://write.blog.csdn.net/postedit?ticket=ST-491405-OGjDDusZeyMgVQ7bHW7f-pa...

    全栈程序员站长
  • PDF能直接编辑吗?如何编辑PDF文件

    PDF能直接编辑吗?相信大家都有同样的疑问吧,大家都觉得PDF文件特殊,应该不能直接进行编辑,如果尝试过编辑却没有成功,那可能是你没有找对方法,下面小编教你一招...

    用户5843321
  • 普通服务器能搭建云游戏吗?搭建云游戏平台需要做什么准备?

    对互联网有一定了解的人都知道服务器是非常重要的,无论是各种网站还是网络游戏都需要服务器的支持,现在市面上有很多家专门提供服务器搭建支持的厂商,能够为企业以及个人...

    用户8715145
  • Kitten编程猫的工程文件 bcm,能发布成Android平台的apk文件吗

    https://shequ.codemao.cn/community/367019

    Jerry Wang
  • I/O多路复用select/poll/epoll

    早期操作系统通常将进程中可创建的线程数限制在一个较低的阈值,大约几百个。因此, 操作系统会提供一些高效的方法来实现多路IO,例如Unix的select和poll...

    WindSun
  • linux 网络编程 I/O复用 select,poll ,epoll

    http://blog.csdn.net/zs634134578/article/details/19929449

    bear_fish
  • 杂谈

    以ae.c/aeProcessEvents(其中包含文件事件分派器)为主的源码让我受益匪浅。该函数作用是完成事件处理的一次循环。 ae_epoll.c/aeA...

    平凡的学生族
  • 阿里一面面经C++

    【每日一语】绝对不要做你的敌人希望你做的事情,原因很简单,因为敌人希望你这样做。——拿破仑

    牛客网
  • 从实例看muduo网络库各模块交互过程

    1、channel 2、Poller 和它的子类 EpollPoller 3、EventLoop 4、Thread、EventLoopThread、Eve...

    看、未来
  • (修订)斩获腾讯微信后台开发offer大神的近1.5W字的面试干货分享

    微信又改版了,为了方便第一时间看到我的推送,请按照下列操作,设置“置顶”:点击上方蓝色字体“程序员乔戈里”-点击右上角“…”-点击“设为星标”。加星标不迷路!

    乔戈里
  • 你有普通用户使用特权端口 (1024 以下) 的需求吗,或许这篇文章能帮你彻底解决!

    众所周知,在 Linux 系统下,只允许 Root 用户运行的程序才可以使用特权端口 ( 1024 以下的端口 )。如果在普通用户下使用特权端口将会报错。

    iMike
  • select,poll,epoll,IO多路复用进化史

      IO多路复用中的 “多路” 指的是同时监听多个打开文件(socket或者其他文件设备),“复用” 指的是复用一个 进程/线程 去监听这些打开文件

    执生
  • 多路复用_java多路复用

    socket编程的demo中使用的都是最基本的,但是一般不会真正用在项目中的代码。而实际项目中,需要面临复杂多变的需求环境,比如有多个socket连接,或者服务...

    全栈程序员站长
  • 深入理解 Linux 的 epoll 机制

    在 Linux 系统之中有一个核心武器:epoll 池,在高并发的,高吞吐的 IO 系统中常常见到 epoll 的身影。

    KevinYan
  • 深入了解epoll模型 -- 开卷有益

    上网一搜epoll,基本是这样的结果出来:《多路转接I/O – epoll模型》,万变不离这个标题。 但是呢,不变的事物,我们就更应该抓出其中的重点了。 ...

    看、未来

扫码关注腾讯云开发者

领取腾讯云代金券