epoll不能用于monitor regular file

昨天看到TLPI书上的这个结论时,有些奇怪,为啥epoll不能作用于regular file呢?之前用select和poll的时候也没有这条限制啊。今天来了经过google学习,终于大概搞懂了。其实select和poll也是“不支持”对regular file进行监控的,只不过它们被设计为可以接受regular file的fd,只是默认对任何event都全部返回True。epoll在设计的时候,考虑到既然对regular file‘s fd进行polling是没意义的,干脆我就不接受这种类型的fd,所以如果你传入一个真实文件的fd给epoll,它会直接报错返回-1,并将errno设置为EPERM错误码。

 

下面是一些有助于理解的文字片段,摘录自文章结尾给出的参考文献:

It doesn't work that way for file backed file descriptors.There's no way to know a file is or isn't ready for writing, unless you had
some way of defining (say) how much data is in the write buffer for that FD.
Linux/FreeBSD at least don't supply this to you.Similarly, there's no way to know a file is or isn't ready for reading, unless
you had some way to tell the OS to begin "prefetching" for you, and only
signify to you there was file IO ready when some had been read.So no, it doesn't work for disk files.Adrian=======================================poll/select/etc technically support regular file descriptors. There is
no error to pass regular FDs to them. It just useless because regular
file always available for read and always available for write.
Therefore, callbacks bound to such descriptors will be called at every
event-loop round.
 =========================================POSIX mandates that regular files always return ready for reading or
writing. IEEE Std 1003.1-2008 says, regarding the poll() interface, that Regular files shall always poll TRUE for reading and writing.
For select(), File descriptors associated with regular files shall always select
true for ready to read, ready to write, and error conditions.

The reasons for this are based on historical and modern implementations
(neither the BSDs nor Linux have an asynchronous block layer), but
regardless it's a part of the abstract interface and won't change anytime
soon even if the implementations change in a way that supports non-blocking
reads. AIO in Linux, for example, AFAIK, is still done using threads, either
preemptible userland threads or kernel work queue threads.  ===============================================What you are trying to do doesn't make any sense. 

For a socket, for example, "ready to read" can mean that there's data 
that a "read" could return without blocking. However, with a file, the 
system has no idea where in the file you'd like to read, so it cannot 
know whether that "read" could return without blocking. 

For a socket, for example, "ready to write" can mean that the other 
side has acknowledged data or enlarged the window or it can mean 
there's space in the local socket send buffer. For a file, the system 
has no idea where you might want to write in the file and system cache 
space is shared and so is unlikely to still be available by the time 
you get around to calling write. 

So even if you could add a regular file to an epoll set, there would 
be no point. If you did ever get a 'ready to read' or 'ready to write' 
indication, you would have no idea what it meant. 

DS  ============================================The problem is that non-blocking I/O isn't specified for regular files 
either. So how many bytes have to be ready for the file to be "ready 
for read". If it woke the process with just one byte ready to read, 
the process would block on the "read" for more than one byte. 

The reason 'select', 'poll', and 'epoll' work so well for sockets is 
because sockets have a well-defined non-blocking API. Generally, 
people use these functions to discover when to attempt non-blocking 
operations in designs where it's important the thread not block. 

Because no such non-blocking API exists for local files (other than 
AIO which doesn't require discovery anyway), a discovery mechanism 
wouldn't really have any use if there was one. 

So while "ready for read" could be defined for files in this way, it 
would have almost no use. A way to discover that a file had been 
modified would be much more useful, and so that is provided. 

DS  ===============================================The problem is the definition of "available". What does it mean for
data to be "available" in a regular file? Does that mean it is not
past the EOF? Does it mean that it's in cache? Or what? (因为没法界定,所以不好支持啊……)

DS ===============================================

 (试想一下你在使用普通磁盘文件时的操作,其实都是阻塞的。对于磁盘文件来说,根本不存在NON_BLOCKING模式。为什么?因为不管你想阻塞还是不想阻塞,它都需要从磁盘盘片上去一个一个字节读进来,但是磁盘的状态是没法预知的,万一你遇上一个破旧的软盘,你即使读取文件的已有部分,它还是会阻塞你的进程的,而且还是Uninterruptible Blocking!所以对于磁盘文件来说,你使用的、你用到的、你需要的都是阻塞模式,因此Linux中不支持磁盘文件的NON_BLOCKING模式,也不需要支持!)

Normal file I/O is blocking in the sense that the function will not
return, stalling the process as long as needed, until the operation
definitively succeeds or fails. It is expected that this will be
"soon", but that isn't always the case. However, it is not the typical
blocking behavior because the process is not interruptible.

DS

===============================================

 

想了解细节,就去看参考文献吧!

 

 

 

 

参考文献:

http://www.groupsrv.com/linux/about159067.html

http://archives.seul.org/libevent/users/Aug-2011/msg00002.html

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值