文章目录

前言

和网络 IO 一样,文件读写同样是一个费事的操作。

默认情况下,Python 使用的是系统的阻塞读写。这意味着在 asyncio 中如果调用了f = file('xx')

f.read()

会阻塞事件循环。

本篇简述如何用 asyncio.Future 对象来封装文件的异步读写。

代码在 GitHub。目前仅支持 Linux。

阻塞和非阻塞

首先需要将文件的读写改为非阻塞的形式。在非阻塞情况下,每次调用 read 都会立即返回,如果返回值为空,则意味着文件操作还未完成,反之则是读取的文件内容。

阻塞和非阻塞的切换与操作系统有关,所以本篇暂时只写了 Linux 版本。如果有过 Unix 系统编程经验,会发现 Python 的操作是类似的。flag = fcntl.fcntl(self.fd, fcntl.F_GETFL)

if fcntl.fcntl(self.fd, fcntl.F_SETFL, flag | os.O_NONBLOCK) != 0:

raise OSError()

Future 对象

Future 对象类似 Javascript 中的 Promise 对象。它是一个占位符,其值会在将来被计算出来。我们可以使用result = await future

在 future 得到值之后返回。而使用future.set_result(xxx)

就可以设置 future 的值,也意味着 future 可以被返回了。await 操作符会自动调用 future.result() 来得到值。

loop.call_soon

通过 loop.call_soon 方法可以将一个函数插入到事件循环中。

至此,我们的异步文件读写思路也就出来了。通过 loop.call_soon 调用非阻塞读写文件的函数。若一次文件读写没有完成,则计算剩余所学读写的字节数,并再次插入事件循环直至读写完毕。

可以发现其就是把传统 Unix 编程里,非阻塞文件读写的 while 循环换成了 asyncio 的事件循环。

下面是这一过程的示意代码。1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18def (self, future, n, total):

res = self.fd.read(n)

if res is None:

self.loop.call_soon(self.read_step, future, n, total)

return

if not res:

future.set_result(bytes(self.rbuffer))

return

self.rbuffer.extend(res)

self.loop.call_soon(self.read_step, future, self.BLOCK_SIZE, total)

def read(self, n=-1):

future = asyncio.Future(loop=self.loop)

self.rbuffer.clear()

self.loop.call_soon(self.read_step, future, min(self.BLOCK_SIZE, n), n)

return future

asyncio 文件io高并发_用 asyncio 封装文件读写相关推荐

  1. vue前端上传文件夹的插件_基于vue-simple-uploader封装文件分片上传、秒传及断点续传的全局上传插件...

    1. 前言 之前公司要在管理系统中做一个全局上传插件,即切换各个页面的时候,上传界面还在并且上传不会受到影响,这在vue这种spa框架面前并不是什么难题.然而后端大佬说我们要实现分片上传.秒传以及断点 ...

  2. asyncio 文件io高并发_python教程:使用 async 和 await 协程进行并发编程

    python 一直在进行并发编程的优化, 比较熟知的是使用 thread 模块多线程和 multiprocessing 多进程,后来慢慢引入基于 yield 关键字的协程. 而近几个版本,python ...

  3. java 多进程写一个文件_java高并发多线程及多进程同时写入文件研究

    测试&思考: 环境:windows 七.linux centos 6.三.java8html java多线程同时写一个文件 java高并发环境下多线程同时写入一个文件时, 经过 FileLoc ...

  4. python链家网高并发异步爬虫asyncio+aiohttp+aiomysql异步存入数据

    python链家网二手房异步IO爬虫,使用asyncio.aiohttp和aiomysql 很多小伙伴初学python时都会学习到爬虫,刚入门时会使用requests.urllib这些同步的库进行单线 ...

  5. aiohttp保存MySQL_python链家网高并发异步爬虫asyncio+aiohttp+aiomysql异步存入数据

    python链家网二手房异步IO爬虫,使用asyncio.aiohttp和aiomysql 很多小伙伴初学python时都会学习到爬虫,刚入门时会使用requests.urllib这些同步的库进行单线 ...

  6. 前端调用mysql异步_python链家网高并发异步爬虫asyncio+aiohttp+aiomysql异步存入数据...

    python链家网二手房异步IO爬虫,使用asyncio.aiohttp和aiomysql 很多小伙伴初学python时都会学习到爬虫,刚入门时会使用requests.urllib这些同步的库进行单线 ...

  7. python异步高并发_通过python异步通讯方式构建高并发压力测试工具

    背景说明 在工作中,要对一个接口进行压测,我当时就想通过python自己编写一个压力发生器. 初步方案(单线程循环发送) 通过循环向服务端发送请求,代码如下: #采用单步循环的方式循环测试 impor ...

  8. oom 如何避免 高并发_【转载】如何避免OOM?看Greenplum的最佳实践

    导致数据库 OOM 报错的原因可能有: 数据库节点内存不足 操作系统内存相关的内核参数配置不当 数据倾斜,导致某些查询时,某个 SEGMENT 需要申请的内存超大 查询倾斜,例如某些聚合.窗口函数的分 ...

  9. python go高并发_天下武功为快不破,戏说Python与Go高并发争锋!

    在这个以斗气大陆横行的世界,每一个大的势力宗门都有自己的杀手锏的功法,比如老牌的古族有C++这样的巨无霸语言,药族有C语言,几乎斗气大陆所有的操作系统都是用C语言做的,毕竟斗气都要靠吃丹药维持.而实力 ...

最新文章

  1. mvc学习-编辑提交需要注意-mvc重点
  2. Spring Boot 构建多租户 SaaS 平台核心技术指南
  3. Blending and Bagging
  4. HTML/CSS——PC端QQ飞车官网首页
  5. mysql权限层级体系_MySQL权限体系介绍
  6. 在Controller中使用AOP
  7. BugkuCTF-MISC题细心的大象
  8. RocketMQ单机版本安装(windows环境)
  9. mysql ON DUPLICATE KEY UPDATE重复插入时更新
  10. java udp发送速率_项目总结22:Java UDP Socket数据的发送和接收
  11. 服务器常见问题:服务器使用过程中感觉不流畅、卡顿
  12. josn转bln的方法
  13. 【2021年度总结】旧年的喜怒哀乐和新年的虎啸龙腾
  14. Job for postfix.service failed because the control process exited with error code. See systemctl st
  15. 磁力计很容易受到干扰
  16. Linux下kill -9杀不死进程或杀死又自动启动,解决
  17. 腾讯搜搜高管吴军离职的传闻与真相
  18. 机器学习 大数据 数据挖掘_什么是机器学习? 来自数据的情报
  19. 4-Points Congruent Sets for Robust Pairwise Surface Registration——4PCS阅读笔记
  20. Latex 环境下“中文字体”的使用

热门文章

  1. Vue后台数据模拟以及抓取线上数据
  2. Mybatis中Mapper.xml文件sql中动态获取----#{}和${}区别
  3. AIM Tech Round 5C. Rectangles 思维
  4. 痞子衡嵌入式:ARM Cortex-M文件那些事(1)- 源文件(.c/.h/.s)
  5. SecondaryNameNode的Inconsistent checkpoint fields异常
  6. C++模板类中使用静态成员变量(例如Singleton模式)
  7. 屌丝也能开发安卓版2048(App Inventor)
  8. ABI (应用程序二进制接口)
  9. js中解决函数中使用外部函数局部变量的问题(闭包问题)
  10. c++重载、覆盖和隐藏