我有一个现有的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)
作为一个相对的菜鸟,文件对我来说并不十分清楚。任何建议将不胜感激。
答案 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
或一些外部手段,如套接字或管道)或明确地共享它们(通过Value
或Array
,或某些外部手段,如文件)。
对于更实际的用例,您通常不希望直接控制进程正在执行的操作;你想创建一个进程池,只是排队工作,以便下一个免费的进程完成。为此,您需要multiprocessing.Pool
或concurrent.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)
调用返回一些值,并且您希望在host1
,host2
和host3
上运行它:
def test_3_pooled_responses():
pool = multiprocessing.Pool(3)
responses = pool.map(test_response, ['host1', 'host2', 'host3'])
pool.close()
pool.join()