非阻塞文件的结尾

如何解决非阻塞文件的结尾

在非阻塞模式下如何检测文件结尾?     

解决方法

至少在POSIX(包括Linux)上,显而易见的答案是不存在非阻塞常规文件。常规文件始终会阻塞,而O_NONBLOCK会被静默忽略。 同样,poll()/ select()等。会始终告诉您,指向常规文件的fd已准备好进行I / O,无论数据是在页面缓存中还是在磁盘上(大多数与读取有关)都准备就绪。 编辑而且,由于O_NONBLOCK是常规文件的禁忌,因此常规文件上的read()永远不会将errno设置为EAGAIN,这与对该问题的另一个答案相反。 EDIT2参考: 从POSIX(p)select()规范中:\“与常规文件关联的文件描述符应始终为true,以准备读取,准备写入和出现错误情况。” 从POSIX poll()规范中:\“常规文件应始终将TRUE轮询以进行读写。 上面的内容足以暗示,虽然可能没有严格禁止,但非阻塞常规文件没有任何意义,因为除了忙碌等待之外,没有其他方法可以轮询它们。 除上述以外,至少还有一些间接证据 根据POSIX open()规范:定义了引用管道,块特殊文件和字符特殊文件的文件描述符的行为。 \“否则,未指定O_NONBLOCK的行为。” 一些相关链接: http://tinyclouds.org/iocp-links.html http://www.remlab.net/op/nonblock.shtml http://davmac.org/davpage/linux/async-io.html 而且,即使在stackoverflow上: 非阻塞IO可以使常规文件读取受益吗? 正如R.的答案所指出的那样,由于页面缓存的工作原理,对于常规文件的非阻塞不是很容易定义。例如。如果通过某种机制发现已经准备好在页面缓存中读取数据,然后在读取数据之前,内核由于内存压力而决定将该页面从缓存中踢出,该怎么办?对于套接字和管道,它是不同的,因为正确性要求不要像这样丢弃数据。 另外,如何选择/轮询可搜索的文件描述符?您将需要一些新的API,这些API支持指定您感兴趣的文件中的哪个字节范围。该API的内核实现将与VM系统绑定,因为它将需要阻止您的页面。对被踢出感兴趣。这意味着这些页面将计入进程锁定页面的限制(请参阅ulimit -l)以防止DOS。而且,这些页面什么时候才能解锁?等等。     ,这是一个非常好的问题。非阻塞套接字从“ 0”返回一个空字符串,而不是抛出“ 1”以指示没有可用数据。不过对于文件来说,似乎没有任何可用于Python的直接指示符。 我能想到的唯一一种检测EOF的机制是在接收到空字符串后将文件的当前位置与文件的整体大小进行比较:
def read_nonblock( fd ):
    t = os.read(fd,4096)
    if t == \'\':
        if os.fstat(fd).st_size == os.lseek(fd,os.SEEK_CUR):
            raise Exception(\"EOF reached\")
    return t
当然,这假定非阻塞模式下的常规文件实际上将立即返回,而不是等待从磁盘读取数据。我不确定在Windows或Linux上是否如此。值得测试,但是即使在非阻塞模式下读取常规文件也只会在遇到实际EOF时返回空字符串,我不会感到惊讶。     ,在c ++(YMMV)中很好用的一个好技巧是,如果返回的数据量小于缓冲区的大小(即缓冲区未满),则可以安全地假定事务已完成。那么文件的最后部分就有1 / buffersize的可能性完全填满了缓冲区,因此对于较大的缓冲区,您可以合理地确定事务将以未填充的缓冲区结束,因此如果您测试数据量返回缓冲区大小,并且它们不相等,您知道发生了错误或事务已完成。不知道这是否将转换为python,但这是我发现EOF的方法     ,即使选择EOF,也不会选择告诉您有什么要阅读的内容吗?如果它告诉您有什么要阅读的东西,而您又没有得到任何东西,那么它一定是EOF。我相信插座就是这种情况。     ,对于文件,将文件描述符设置为非阻塞将无济于事-所有IO都会阻塞。 如果您确实需要非阻塞文件IO,则需要查看ѭ3和朋友,它们是用于文件访问的异步IO工具。这些是非常不可移植的,并且有时工作起来有些混乱-因此,大多数项目实际上已经决定对IO使用单独的进程(或线程),并在那里仅使用阻塞IO。 再说一遍,也许您对以某种方式“选择”文件感兴趣:当文件增长时,您会收到通知。您可能已经意识到
select
poll
等不起作用。大多数软件都是通过每秒轮询一次文件来完成此操作的,例如\“ tail -f \”通过轮询来做到这一点很神奇。但是,您也可以让内核在文件写入时通知您-
inotify
和朋友发生这种情况。有一些方便的库可以为您完成所有这些工作,因此您不必自己弄乱细节。即,对于python,分别为
inotifyx
pyinotify
。     

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


依赖报错 idea导入项目后依赖报错,解决方案:https://blog.csdn.net/weixin_42420249/article/details/81191861 依赖版本报错:更换其他版本 无法下载依赖可参考:https://blog.csdn.net/weixin_42628809/a
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下 2021-12-03 13:33:33.927 ERROR 7228 [ main] o.s.b.d.LoggingFailureAnalysisReporter : *************************** APPL
错误1:gradle项目控制台输出为乱码 # 解决方案:https://blog.csdn.net/weixin_43501566/article/details/112482302 # 在gradle-wrapper.properties 添加以下内容 org.gradle.jvmargs=-Df
错误还原:在查询的过程中,传入的workType为0时,该条件不起作用 <select id="xxx"> SELECT di.id, di.name, di.work_type, di.updated... <where> <if test=&qu
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct redisServer’没有名为‘server_cpulist’的成员 redisSetCpuAffinity(server.server_cpulist); ^ server.c: 在函数‘hasActiveC
解决方案1 1、改项目中.idea/workspace.xml配置文件,增加dynamic.classpath参数 2、搜索PropertiesComponent,添加如下 <property name="dynamic.classpath" value="tru
删除根组件app.vue中的默认代码后报错:Module Error (from ./node_modules/eslint-loader/index.js): 解决方案:关闭ESlint代码检测,在项目根目录创建vue.config.js,在文件中添加 module.exports = { lin
查看spark默认的python版本 [root@master day27]# pyspark /home/software/spark-2.3.4-bin-hadoop2.7/conf/spark-env.sh: line 2: /usr/local/hadoop/bin/hadoop: No s
使用本地python环境可以成功执行 import pandas as pd import matplotlib.pyplot as plt # 设置字体 plt.rcParams['font.sans-serif'] = ['SimHei'] # 能正确显示负号 p
错误1:Request method ‘DELETE‘ not supported 错误还原:controller层有一个接口,访问该接口时报错:Request method ‘DELETE‘ not supported 错误原因:没有接收到前端传入的参数,修改为如下 参考 错误2:cannot r
错误1:启动docker镜像时报错:Error response from daemon: driver failed programming external connectivity on endpoint quirky_allen 解决方法:重启docker -> systemctl r
错误1:private field ‘xxx‘ is never assigned 按Altʾnter快捷键,选择第2项 参考:https://blog.csdn.net/shi_hong_fei_hei/article/details/88814070 错误2:启动时报错,不能找到主启动类 #
报错如下,通过源不能下载,最后警告pip需升级版本 Requirement already satisfied: pip in c:\users\ychen\appdata\local\programs\python\python310\lib\site-packages (22.0.4) Coll
错误1:maven打包报错 错误还原:使用maven打包项目时报错如下 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources)
错误1:服务调用时报错 服务消费者模块assess通过openFeign调用服务提供者模块hires 如下为服务提供者模块hires的控制层接口 @RestController @RequestMapping("/hires") public class FeignControl
错误1:运行项目后报如下错误 解决方案 报错2:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project sb 解决方案:在pom.
参考 错误原因 过滤器或拦截器在生效时,redisTemplate还没有注入 解决方案:在注入容器时就生效 @Component //项目运行时就注入Spring容器 public class RedisBean { @Resource private RedisTemplate<String
使用vite构建项目报错 C:\Users\ychen\work>npm init @vitejs/app @vitejs/create-app is deprecated, use npm init vite instead C:\Users\ychen\AppData\Local\npm-