从Python运行程序并捕获C输出IN MANY THREADS

时间:2012-10-13 15:06:12

标签: python

我有一个C程序,需要两个args并输出一个数字。

  

./ a.out 2 3(例如)。

它做了一些计算上昂贵的操作,所以我想知道我是否可以使用Python的多处理库来运行一堆C程序,然后将所有数字编译成列表或表或某些数据结构?

感谢。

这不是重复,因为我的问题是我如何能够并行(E.G. MANY THREADS)!

我不知道如何让一个Python程序运行几百个C程序并将所有输出捕获到Python列表中。看来,使用过程是1比1。

4 个答案:

答案 0 :(得分:2)

您可以使用ThreadPool并行运行多个任务。

from multiprocessing.pool import ThreadPool
import subprocess
def f(x):
    a, b = x
    res = subprocess.check_output(["./a.out", str(a), str(b)])
    return int(res.strip())
p = ThreadPool()
results = p.map(f, [(2,3), (5,6), (9,10)])

答案 1 :(得分:1)

您可以使用subprocess.Popen一次运行多个进程而无需使用线程。

如果它们的输出足够短以适合操作系统缓冲区,则相当容易:

要异步启动程序,请使用

subprocess.Popen(['command', args],stdout=subprocess.PIPE)

只需对所有命令执行此操作,并将结果放在数组中。

然后:

 for process in subprocesses:
   process.wait()
   stdout,stderr = process.communicate()

如果子进程输出大量数据,这将不起作用,因为wait()将死锁:进程想要写更多,但缓冲区已满,并且您正在等待该进程在您阅读之前完成。 / p>

在这种情况下,您需要查看select.poll()或类似的API:s

答案 2 :(得分:0)

您可以尝试使用python的子进程模块,它允许您启动进程,等待它的结束并捕获它的所有输出(stdout,stderr)。

您可以在此处查看子流程文档:http://docs.python.org/library/subprocess.html

你可以看看我的例子:

#file t1.py

import time

def __main__():
    time.sleep(10)
    print(10)

if __name__ == "__main__":
    __main__()

#file: t2.py

import time
import subprocess

def __main__():
    N = 10
    V = 0

    pp = [subprocess.Popen("t1.py", stdout = subprocess.PIPE, shell = True) for _ in range(0, N)]
    oo = ["" for _ in range(0, N)]
    ff = [False for _ in range(0, N)]
    while True:
        for i in range(0, N):
            oo[i] += pp[i].stdout.read()
            if pp[i].poll() != None:
                ff[i] = True
        done = all(ff)
        if done:
            for o in oo:
                V += int(o)
            break
    print(V)

if __name__ == "__main__":
    __main__()

文件t2.py完全符合您的要求。文件t1.py模拟长时间运行的C程序。

我编辑了我的例子,因为perh是正确的,因为子进程创建新进程所以不需要线程。如果你的程序有一个巨大的输出(大于管道长度限制),他也是正确的,因此我们必须从管道读取并等待进程完成。

答案 3 :(得分:0)

您可能希望使用Pythons ctypes模块,它可以让您将C程序编译到库中,然后从您的python脚本中调用该库。

此外,swig项目将允许您从Python调用C或C ++代码而不会有太多麻烦(请参阅this answer)。

如果你走这条路,你可能应该考虑使用Threadpool或其他一些机制来并行调用。