【问题标题】:incorporating subprocess into an existing script将子流程合并到现有脚本中
【发布时间】:2013-02-01 22:28:33
【问题描述】:

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

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

【问题讨论】:

  • 请注意,(子)进程与线程不同......
  • 如果您想像使用线程一样使用子进程,请使用multiprocessing 模块。 (subprocess 模块用于运行其他程序,而不是用于并行化您自己的程序。)

标签: python subprocess


【解决方案1】:

如果你想显式控制你正在运行的进程,你需要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()

【讨论】:

  • 感谢您提供这些信息和示例,因为它非常有帮助
猜你喜欢
  • 2014-11-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-07-16
  • 1970-01-01
  • 2011-04-30
相关资源
最近更新 更多