V2EX 首页   注册   登录
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python 学习手册
Python Cookbook
Python 基础教程
Python Sites
PyPI - Python Package Index
http://www.simple-is-better.com/
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
V2EX  ›  Python

Python 的异步如何应用在普通操作上?

  •  
  •   billion · 96 天前 · 1059 次点击
    这是一个创建于 96 天前的主题,其中的信息可能已经有所发展或是发生改变。

    目前网上能找到的关于 Python 的异步操作,几乎都是各种 HTTP 请求或者 Sockets 连接。然而却鲜有文章讲解如何用异步来进行普通的操作。

    例如我有一百个 1G 的 txt 文件,我想让 Python 异步读取他们。这个操作用 Python 3.6 的 async 与 await 如何实现呢?

    如果我有很多普通的 Python 操作,例如复制文件,删除大文件等等操作,如何使用异步而不是多线程来完成这些操作?

    如果在 Golang 里面,可以把这些操作放在一个函数中,然后go delete('xxx.txt') 他就会异步去执行了。可是在 Python 里面,似乎有点让人摸不着头脑。

    17 回复  |  直到 2017-07-18 22:43:25 +08:00
        1
    jason0916   96 天前
    文件 io 的话可以看下这个 https://github.com/Tinche/aiofiles

    用协程主要是为了 io 操作不阻塞下一步的代码被执行,可以充分利用 cpu,所以很多例子都是网络 io 方面的
        2
    janxin   96 天前
    只是标准库不提供这个功能,而且本质上来说,网络 IO 在普通 Web 应用里更容易阻塞,本地 IO 一般会更快。何况,实在不行还能上 SSD 不是
        3
    billion   96 天前
    @janxin 实际上因为并非所有的操作都有第三方库支持,所以我希望能找到一种通用的异步开发方法。
        4
    lolizeppelin   96 天前 via Android
    不改任何代码想实现的话直接 eventlet 就好了
        5
    yonka   96 天前
    只有阻塞 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   95 天前
    @lolizeppelin 这个可以实现对任何操作进行异步吗?
        7
    billion   95 天前
    @yonka 这里的 self.executor 可以是任何函数吗?
        8
    yonka   95 天前
    @billion 既然是 executor 那就应该是个 executor 呀
        9
    billion   95 天前
    @yonka 那这个 executor 是什么东西。写法有要求吗
        10
    yonka   95 天前
    @billion refer to `https://www.baidu.com/s?wd=python+executor`
        11
    yylucifer   95 天前
    @billion 你这个想法我有过,经过几个月的学习和尝试,事实告诉我这可能做不到。
        12
    lolizeppelin   95 天前
    eventlet 通过 hack os 库 实现不改代码的 write read 异步
    但是你想不去深入,希望库帮你什么都异步好是做不到的
    不了了解具体原理你用都用不好

    老老实实学习异步的实现过程再找最适合的来用
        13
    linw1995   95 天前
    ```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   95 天前
    用 ThreadPoolExecutor 就可以咯
        15
    billion   95 天前
    @linw1995 你们都理解错题意了。读文件只是举个例子。我希望能实现对任何操作进行异步处理,并且能自定义回调函数。就像 JavaScript 一样。你这个代码没有实现回调函数的功能阿。
        16
    linw1995   94 天前   ♥ 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   94 天前   ♥ 1
    io 异步就用 epoll/select 监控 fd

    密集计算中间自己控制放弃 cpu 一般用协程,yeid 和 greenlet 之类

    封装来封装去底层最后的实现基本都这样,c 怎么写 python 也怎么写
    DigitalOcean
    关于   ·   FAQ   ·   API   ·   我们的愿景   ·   广告投放   ·   鸣谢   ·   1631 人在线   最高记录 3541   ·  
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.0 · 70ms · UTC 14:04 · PVG 22:04 · LAX 07:04 · JFK 10:04
    ♥ Do have faith in what you're doing.
    沪ICP备16043287号-1