将子流程合并到现有脚本中

时间:2013-02-01 22:28:34

标签: python subprocess

我有一个现有的python脚本,我现在要修改它以运行更多的线程(子进程)。出于这个例子的目的,让我们说修改为同时运行3个线程。

顺便提一下,脚本只不过是向Web服务器生成客户端请求并测量响应时间。

#!/usr/bin/python26

from library.rpc.client import EllisClient

ec = EllisClient(ellis_user='fred', ellis_pass='flintstone')
params={'domain_name':'alestel.com','mig_name':'terramexico2'}


def test_response():
    L = []
    L = ec.get_full_domain(params)

if __name__ == '__main__':
    from timeit import Timer

    t = Timer("test_response()", "from __main__ import test_response")
    print t.timeit(number=10)

作为一个相对的菜鸟,文件对我来说并不十分清楚。任何建议将不胜感激。

1 个答案:

答案 0 :(得分:0)

如果您希望明确控制正在运行的流程,则需要multiprocessing.Process

def test_3_parallel_responses():
    procs = [multiprocess.Process(target=test_response) for _ in range(3)]
    for proc in procs:
        proc.start()
    for proc in procs:
        proc.join()

这就是它的全部内容。

线程和进程之间存在各种差异,但最重要的是您不能在进程之间隐式共享值;你必须传递它们(通过启动args并返回值,或通过Queue或一些外部手段,如套接字或管道)或明确地共享它们(通过ValueArray,或某些外部手段,如文件)。

对于更实际的用例,您通常不希望直接控制进程正在执行的操作;你想创建一个进程池,只是排队工作,以便下一个免费的进程完成。为此,您需要multiprocessing.Poolconcurrent.futures.ProcessPoolExecutor。后者有点简单,但需要Python 3.2或第三方库,所以我将展示前者:

def test_3_pooled_responses():
    pool = multiprocessing.Pool(3)
    for i in range(3):
        pool.apply(test_response)
    pool.close()
    pool.join()

更常见的是,您希望实际将参数传递给函数。在最简单的情况下,这实际上使事情变得更简单 - 如果您可以将顺序版本编写为列表理解或map调用,则可以将并行版本编写为pool.map调用。假设您有一个test_response(host)调用返回一些值,并且您希望在host1host2host3上运行它:

def test_3_pooled_responses():
    pool = multiprocessing.Pool(3)
    responses = pool.map(test_response, ['host1', 'host2', 'host3'])
    pool.close()
    pool.join()