Python多进程概要分析

bar*_*ley 42 python multiprocessing cprofile

我正在努力弄清楚如何分析一个简单的多进程python脚本

import multiprocessing
import cProfile
import time
def worker(num):
    time.sleep(3)
    print 'Worker:', num

if __name__ == '__main__':
    for i in range(5):
        p = multiprocessing.Process(target=worker, args=(i,))
        cProfile.run('p.start()', 'prof%d.prof' %i)
Run Code Online (Sandbox Code Playgroud)

我正在启动5个进程,因此cProfile会生成5个不同的文件.在每个内部我想看到我的方法'worker'运行大约需要3秒钟,但我只看到'start'method内部正在发生的事情.

如果有人能向我解释,我将不胜感激.

更新:基于已接受答案的工作示例:

import multiprocessing
import cProfile
import time
def test(num):
    time.sleep(3)
    print 'Worker:', num

def worker(num):
    cProfile.runctx('test(num)', globals(), locals(), 'prof%d.prof' %num)


if __name__ == '__main__':
    for i in range(5):
        p = multiprocessing.Process(target=worker, args=(i,))
        p.start()
Run Code Online (Sandbox Code Playgroud)

zig*_*igg 22

您正在分析流程启动,这就是为什么您只看到p.start()正如您所说的那样 - 并p.start()在子流程启动后返回.您需要在worker方法内部进行概要分析,这将在子进程中调用.

  • 你能说明如何做到这一点吗? (2认同)

min*_*ker 10

必须更改源代码进行分析还不够酷。让我们看看你的代码应该是什么样的:

import multiprocessing
import time
def worker(num):
    time.sleep(3)
    print('Worker:', num)

if __name__ == '__main__':
    processes = []
    for i in range(5):
        p = multiprocessing.Process(target=worker, args=(i,))
        p.start()
        processes.append(p)
    for p in processes:
        p.join()
Run Code Online (Sandbox Code Playgroud)

join在这里添加了这样你的主要进程将在退出之前等待你的工作人员。

尝试代替 cProfile viztracer

通过安装它pip install viztracer。然后使用多进程功能

viztracer --log_multiprocess your_script.py

它将生成一个 html 文件,在时间轴上显示每个流程。(使用 AWSD 缩放/导航)

脚本的结果

当然,这包括一些您不感兴趣的信息(例如实际多处理库的结构)。如果您对此感到满意,那么就可以开始了。但是,如果您只想为您的函数提供更清晰的图表worker()。尝试一下log_sparse功能。

首先,装饰你想要登录的函数@log_sparse

from viztracer import log_sparse

@log_sparse
def worker(num):
    time.sleep(3)
    print('Worker:', num)
Run Code Online (Sandbox Code Playgroud)

然后运行viztracer --log_multiprocess --log_sparse your_script.py

稀疏日志

只有您的工作函数(耗时 3 秒)才会显示在时间轴上。