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

python subprocess.Popen 运行多进程的 shell 写文件导致覆盖如何解决

  •  
  •   fxxkgw · 2015-06-08 10:15:28 +08:00 · 2859 次点击
    这是一个创建于 3492 天前的主题,其中的信息可能已经有所发展或是发生改变。

    Python2.6.6
    shell脚本中使用多进程
    for file in ${dir}*; do
    {
    cat $abc | grep "${def}" | awk -F'[ ,]+' -f $hij
    }&
    done
    wait

    fout=tempfile.TemporaryFile()
    subprocess.Popen(args=self.cmd.encode('utf-8'), stdout=self.stdout, stderr=self.stderr, shell=True, cwd=self.cwd)
    out=fout.read() #获取最终数据
    awk中用printf输出过滤出的数据到self.stdout中,现在发现当起多个awk并行执行时,获取的数据有覆盖的情况,应该是同时写fout时没锁导致,但是Popen参数里没发现有控制的地方,请问如何处理呢?

    第 1 条附言  ·  2015-06-08 16:30:23 +08:00
    已经改好了,现在使用python多进程 也就是multiprocessing的Pool代替了shell的多进程解决了无锁写覆盖问题。
    感谢回复
    :)
    7 条回复    2015-06-08 11:26:48 +08:00
    henryon
        1
    henryon  
       2015-06-08 10:47:30 +08:00
    弱弱的问下,你的需求是什么? 方便贴下原数据,目标期望么?
    guojinyun
        2
    guojinyun  
       2015-06-08 10:49:00 +08:00
    我一般是把结果放到一个队列中,再来一个线程把队列中的内容写出.
    fxxkgw
        3
    fxxkgw  
    OP
       2015-06-08 11:06:57 +08:00
    @henryon
    由于原始的比较复杂些,我简单写了个例子
    我先写了个python 然后运行shell 然后运行awk 内容如下:
    test.py

    import veasyprocess
    import os

    cmd = "sh writefile.sh"
    PWD = os.getcwd()
    #veasyprocess模块中使用的就是subprocess.Popen方法,只是封装了下面两行
    #fout=tempfile.TemporaryFile()
    #subprocess.Popen(args=self.cmd.encode('utf-8'), stdout=self.stdout, stderr=self.stderr, shell=True, cwd=self.cwd)

    status, outs = veasyprocess.shell_2_tempfile(_cmd = cmd, _cwd = PWD, _timeout = 240)
    print status
    print outs
    ============================================
    wirtefile.sh
    for((i=0; i<10; i++)); do
    {
    awk -f error.awk writefile.sh
    }&
    done
    wait

    error.awk
    END {
    for(i=0; i<10000; i++) {
    printf "hello world 11111 22222 33333 44444 55555 66666\n"
    }
    }
    ~
    输出内容有下面这种
    hello world 11111 22222 33333 44444 55555 66666
    1 22222 33333 44444 55555 66666
    hello world 11111 22222 33333 44444 55555 66666
    hello world 11111 22222 33333 44444 55555 66666
    hello world 11111 22222 33333 44hello world 11111 22222 33333 44444 55555 66666
    hello world 11111 22222 33333 44444 55555 66666

    输出的内容明显有覆盖现象,要达到的效果就是数据无覆盖,即每行都是完整的hello world 11111 22222 33333 44444 55555 66666
    des
        4
    des  
       2015-06-08 11:12:01 +08:00
    那为什么不直接用python处理呢?
    fxxkgw
        5
    fxxkgw  
    OP
       2015-06-08 11:15:18 +08:00
    @des 嗯 数据量比较大,awk是C写的 速度比python快的多。
    des
        6
    des  
       2015-06-08 11:20:54 +08:00
    @fxxkgw 好像快不到哪里去吧……
    hahastudio
        7
    hahastudio  
       2015-06-08 11:26:48 +08:00
    -为什么不直接改 shell 脚本呢-
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2662 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 06:30 · PVG 14:30 · LAX 22:30 · JFK 01:30
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.