【问题标题】:nonblocking subprocesses in pythonpython中的非阻塞子进程
【发布时间】:2013-02-17 19:06:50
【问题描述】:

对于 perl 的包装器,我需要 python 中的非阻塞子进程(有各种类型的 shell io)。此外,我对 shell 输出和返回值感兴趣。有时返回值为 0,但代码实际上并没有做任何事情。
所以我现在可以使用 subprocess.call() (非阻塞但不是 shell 输出)或 subprocess.Popen() (阻塞但 shell 输出)。

我做了一些阅读,但唯一的解决方案似乎是有一个单独的队列来执行此操作。我错过了什么更容易的事情吗?

【问题讨论】:

    标签: python-2.7 subprocess nonblocking tcsh


    【解决方案1】:

    subprocess.Popen 本身并不是阻塞的。您仍然可以使用proc.stdin.write()proc.stdout.read();唯一的问题是,如果管道填满,您可能会在一侧阻塞,甚至死锁[1]。如果您知道您的子进程只会读取或写入少量数据,则不必担心。

    所以你可以这样做:

    proc = subprocess.Popen(['perl', 'somescript.pl'], stdout=subprocess.PIPE)
    buf = StringIO()
    CHUNKSIZE = 1024  # how much to read at a time
    
    while True:
        # do whatever other time-consuming work you want here, including monitoring
        # other processes...
    
    
        # this keeps the pipe from filling up
        buf.write(proc.stdout.read(CHUNKSIZE))
    
        proc.poll()
        if proc.returncode is not None:
            # process has finished running
            buf.write(proc.stdout.read())
            print "return code is", proc.returncode
            print "output is", buf.getvalue()
    
            break
    

    在更大的应用程序中,您可以将其安排在事件循环、反应器等中发生。


    [1] 操作系统一次只允许这么多数据放入管道中。假设您将cat 作为子进程运行,并将大量数据写入其标准输入。 cat 会将该数据写入它自己的标准输出,直到它填满,然后它会阻塞,直到您的程序从标准输出读取一些数据并清空管道。但是您的程序仍在写入标准输入,cat 不再从中读取,因此管道也会填满。两个进程都将被阻塞写入,等待另一个读取,这永远不会发生。

    【讨论】:

    • 谢谢,我试试看。不应该是很多数据
    猜你喜欢
    • 2014-03-23
    • 2013-05-24
    • 2012-01-18
    • 1970-01-01
    • 1970-01-01
    • 2016-06-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多