0

我有一个现有的 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)

作为一个相对的菜鸟,文档对我来说不是很清楚。任何建议,将不胜感激。

4

1 回答 1

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和返回值,或通过 aQueue或某些外部方式,如套接字或管道)或显式共享它们(通过 a ValueorArray或某些外部方式,如文件)。

对于更实际的用例,您通常不希望直接控制进程在做什么;您想创建一个进程池,然后将作业排队等待下一个空闲的进程完成。为此,您需要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)返回一些值的调用,并且您想在host1host2和上运行它host3

def test_3_pooled_responses():
    pool = multiprocessing.Pool(3)
    responses = pool.map(test_response, ['host1', 'host2', 'host3'])
    pool.close()
    pool.join()
于 2013-02-01T22:58:20.757 回答