目前网上能找到的关于 Python 的异步操作,几乎都是各种 HTTP 请求或者 Sockets 连接。然而却鲜有文章讲解如何用异步来进行普通的操作。
例如我有一百个 1G 的 txt 文件,我想让 Python 异步读取他们。这个操作用 Python 3.6 的 async 与 await 如何实现呢?
如果我有很多普通的 Python 操作,例如复制文件,删除大文件等等操作,如何使用异步而不是多线程来完成这些操作?
如果在 Golang 里面,可以把这些操作放在一个函数中,然后go delete('xxx.txt')
他就会异步去执行了。可是在 Python 里面,似乎有点让人摸不着头脑。
1
JhZ7z587cYROBgVQ 2017-07-17 18:01:28 +08:00
文件 io 的话可以看下这个 https://github.com/Tinche/aiofiles
用协程主要是为了 io 操作不阻塞下一步的代码被执行,可以充分利用 cpu,所以很多例子都是网络 io 方面的 |
2
janxin 2017-07-17 19:19:47 +08:00
只是标准库不提供这个功能,而且本质上来说,网络 IO 在普通 Web 应用里更容易阻塞,本地 IO 一般会更快。何况,实在不行还能上 SSD 不是
|
4
lolizeppelin 2017-07-17 20:50:12 +08:00 via Android
不改任何代码想实现的话直接 eventlet 就好了
|
5
yonka 2017-07-17 20:58:53 +08:00
只有阻塞 api 的操作,可以参考:
```python req_future = asyncio.get_event_loop().run_in_executor( self.executor, lambda: session.send(req) ) r = await asyncio.wait_for(req_future, 15) ``` |
6
billion OP @lolizeppelin 这个可以实现对任何操作进行异步吗?
|
10
yonka 2017-07-18 11:02:50 +08:00
@billion refer to `https://www.baidu.com/s?wd=python+executor`
|
12
lolizeppelin 2017-07-18 11:24:08 +08:00
eventlet 通过 hack os 库 实现不改代码的 write read 异步
但是你想不去深入,希望库帮你什么都异步好是做不到的 不了了解具体原理你用都用不好 老老实实学习异步的实现过程再找最适合的来用 |
13
linw1995 2017-07-18 17:34:11 +08:00
```python
from concurrent.futures import ThreadPoolExecutor as Pool filenames = [...] def readFile(filename): with open(filename, encoding='utf-8') as f: content = f.read() return content # or do what you want with Pool(10) as executor: results = executor.map(readFile, filenames) for result in results: print(result) ``` |
14
linw1995 2017-07-18 17:34:53 +08:00
用 ThreadPoolExecutor 就可以咯
|
15
billion OP @linw1995 你们都理解错题意了。读文件只是举个例子。我希望能实现对任何操作进行异步处理,并且能自定义回调函数。就像 JavaScript 一样。你这个代码没有实现回调函数的功能阿。
|
16
linw1995 2017-07-18 22:10:19 +08:00 1
@billion
仔细看下文档就知道了,如果要回调,就使用 ThreadPoolExecutor().submit(func, args),会返回一个 future 对象,他有 add_done_callback 方法。文档在这,https://docs.python.org/dev/library/concurrent.futures.html#concurrent.futures.Future.add_done_callback 想看例子的,可以看下这篇文章 http://masnun.com/2016/03/29/python-a-quick-introduction-to-the-concurrent-futures-module.html concurrent.futures 是个特别容易使用的异步库,哈哈。twisted 什么的太复杂了,async/await 也挺不错的,写法也还简单,不过题主问的问题是要把普通操作变成异步的……那就是把普通函数做成异步的,我是这么理解的,所以就用这个最合适了。 |
17
lolizeppelin 2017-07-18 22:43:25 +08:00 1
io 异步就用 epoll/select 监控 fd
密集计算中间自己控制放弃 cpu 一般用协程,yeid 和 greenlet 之类 封装来封装去底层最后的实现基本都这样,c 怎么写 python 也怎么写 |