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
dysxjyy
V2EX  ›  Python

萌新请教一下 Python 应该如何并行地调用二进制文件?

  •  
  •   dysxjyy · 2019-03-28 15:10:26 +08:00 · 1971 次点击
    这是一个创建于 1848 天前的主题,其中的信息可能已经有所发展或是发生改变。
    需要用 Python 调用一个用 C 写的仿真器做仿真,但是仿真器是单线程的,我希望能在服务器上并行。

    目前我的办法是写了个脚本用 subprocess 去调用,然后开了好多个终端去执行这个脚本以达到并行的目的。想请教一下有没有更优雅的做法?
    第 1 条附言  ·  2019-03-28 18:34:44 +08:00

    主要是 Popen 貌似有点问题,我是这样写的:

    glps = list(filter(lambda x:'.glp' in x, os.listdir(rootpath+'outputs/')))
    num_threads = len(glps)
    cmd_list = [['python', 'lithosim_one.py', 'evaluation/lithosim%d/'%i, rootpath+'outputs/'+glps[i]] for i in range(num_threads)]
    proc_list = [Popen(cmd, stdout=PIPE, stderr=PIPE) for cmd in cmd_list]
    for p in proc_list:
        p.wait()
    

    假如有 10 个文件要仿真,我的机器是 6 核,它会把 6 个仿完,剩下的 4 个就不继续了,主程序也没有结束。

    ————————————————————————————————————

    百度找到问题了:

    使用 subprocess 模块的 Popen 调用外部程序,如果 stdout 或 stderr 参数是 pipe,并且程序输出超过操作系统的 pipe size时,如果使用 Popen.wait() 方式等待程序结束获取返回值,会导致死锁,程序卡在 wait() 调用上。

    解决方法:把wait()改成communicate()就可以了。

    5 条回复    2019-03-28 18:36:21 +08:00
    no1xsyzy
        1
    no1xsyzy  
       2019-03-28 15:45:44 +08:00
    subprocess 了为什么要好多个终端?直接 Popen 一堆就行了。
    dysxjyy
        2
    dysxjyy  
    OP
       2019-03-28 18:09:40 +08:00
    @no1xsyzy
    主要是 Popen 貌似有点问题,我是这样写的:
    ``` python
    glps = list(filter(lambda x:'.glp' in x, os.listdir(rootpath+'outputs/')))
    num_threads = len(glps)
    cmd_list = [['python', 'lithosim_one.py', 'evaluation/lithosim%d/'%i, rootpath+'outputs/'+glps[i]] for i in range(num_threads)]
    proc_list = [Popen(cmd, stdout=PIPE, stderr=PIPE) for cmd in cmd_list]
    for p in proc_list:
    p.wait()
    ```
    假如有 10 个文件要仿真,我的机器是 6 核,它会把 6 个仿完,剩下的 4 个就不继续了,主程序也没有结束。
    www5070504
        3
    www5070504  
       2019-03-28 18:16:45 +08:00
    @dysxjyy 用线程行不 解释器锁会切换线程的
    haddy
        4
    haddy  
       2019-03-28 18:27:10 +08:00
    试试这个包。https://github.com/kennethreitz/delegator.py
    如果觉得有用,可以点主页上的 saythanks.io 的链接对作者表示感谢。
    dysxjyy
        5
    dysxjyy  
    OP
       2019-03-28 18:36:21 +08:00
    @www5070504 @haddy @no1xsyzy 问题解决了,感谢回复。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   5159 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 594ms · UTC 05:43 · PVG 13:43 · LAX 22:43 · JFK 01:43
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.