V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
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
allenloong
V2EX  ›  Python

新手提问: Python 同时写多个文件的实现方法

  •  
  •   allenloong · 2019-06-22 11:52:03 +08:00 · 5499 次点击
    这是一个创建于 2016 天前的主题,其中的信息可能已经有所发展或是发生改变。
    Python 新手。
    最近遇到一个问题,大概是从一个很大很大的文件中匹配出一堆记录,然后按照规则写入不同的文件里。之前的实现方法是逐条写,但是效率实在是非常感人,想问下有没有更高效的方法。谢谢。
    16 条回复    2019-06-23 01:23:49 +08:00
    binux
        1
    binux  
       2019-06-22 11:57:31 +08:00
    找一个异步文件 io 的库
    lhx2008
        2
    lhx2008  
       2019-06-22 11:57:45 +08:00
    把写的数据缓存到多个 [],用多进程在子进程里面写
    dongxiao
        3
    dongxiao  
       2019-06-22 12:01:09 +08:00
    IO 操作类型的,用多线程就好
    toono
        4
    toono  
       2019-06-22 12:02:17 +08:00
    楼上的方法是通过操作系统的异步进行解决,如果想要屏蔽这些操作系统的细节去实现可以用 celery,通过引入任务队列进行任务分发管理,但是弊端是引入了一个新的组件
    ebingtel
        5
    ebingtel  
       2019-06-22 12:03:38 +08:00
    multiprocessing 库即可,一个进程负责读大文件、把匹配的数据写到多个对应的 queue 中……各个规则可以分别搞个子进程,读取对应的队列,专门写自己的文件(这种方式适合规则不太多的情况,如果太多,进程要开少一点)
    lihongjie0209
        6
    lihongjie0209  
       2019-06-22 12:08:45 +08:00
    先把代码贴出来, 看看是不是你的写法有问题?

    要是在循环中读写文件那肯定慢啊
    allenloong
        7
    allenloong  
    OP
       2019-06-22 12:09:18 +08:00
    @ebingtel @lhx2008 目前是要写好几十个文件
    @toono 我去看看 thx
    Hopetree
        8
    Hopetree  
       2019-06-22 13:43:03 +08:00
    多线程啊,IO 密集型,多线程最优
    clino
        9
    clino  
       2019-06-22 13:48:21 +08:00 via Android
    我可能会用 gevent 写多进程
    0x000007b
        10
    0x000007b  
       2019-06-22 15:19:04 +08:00 via Android
    多线程或者 async
    inframe
        11
    inframe  
       2019-06-22 15:30:50 +08:00 via Android
    多线程,一个线程读取,用个队列传递任务给其他线程,也不用担心读写冲突问题
    毕竟官方 py GIL 保证了多线程就是单线程
    BingoXuan
        12
    BingoXuan  
       2019-06-22 15:36:46 +08:00 via Android
    @inframe
    py 的多线程并非是线程安全的。因为解释出来的字节码顺序是不确定的,也就是线程 a 的操作到一半,线程 b 有可能同样也进入相同的代码了,线程的共享数据会被破坏掉。
    whoami9894
        13
    whoami9894  
       2019-06-22 18:11:32 +08:00 via Android
    @inframe
    你没有理解 GIL
    westoy
        14
    westoy  
       2019-06-22 18:12:47 +08:00
    @inframe IO 是释放 GIL 锁的
    testeststs
        15
    testeststs  
       2019-06-22 20:43:55 +08:00
    生产者 /消费者模型学过吗?
    cabbage
        16
    cabbage  
       2019-06-23 01:23:49 +08:00   ❤️ 1
    一楼 +1,比如 aiofiles [1] 这个库用了并发线程池,默认是 asyncio loop 自带的默认线程池。

    如果只需要异步 io 就上多进程 multiprocessing,开销大也没必要,还增加复杂度,async 多线程够了。
    要是不好引入新依赖的话,`run_in_executor`[2]了解下,让 io 密集操作进入线程池执行,不阻塞其他逻辑。以及 `asyncio.create_task`[3] 或 `asyncio.gather`[4]。

    但是关键 io 代码无论如何都要自行同步管理好,否则会写坏数据,正如 @BingoXuan 提到 py 的多线程不安全

    [1] https://github.com/Tinche/aiofiles
    [2] https://docs.python.org/3/library/asyncio-eventloop.html#asyncio.loop.run_in_executor
    [3] https://docs.python.org/3/library/asyncio-task.html#asyncio.create_task
    [4] https://docs.python.org/3/library/asyncio-task.html#asyncio.gather
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1993 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 00:24 · PVG 08:24 · LAX 16:24 · JFK 19:24
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.