51

我正在努力弄清楚如何分析一个简单的多进程 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)

我正在启动 5 个进程,因此 cProfile 会生成 5 个不同的文件。在每个我想看到我的方法“worker”运行大约需要 3 秒,但我只看到“start”方法内部发生了什么。

如果有人可以向我解释这一点,我将不胜感激。

更新:基于公认答案的工作示例:

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()
4

3 回答 3

27

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

于 2012-06-14T21:36:31.207 回答
4

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

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()

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)

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

稀疏日志

时间轴上只会显示您的工作函数,耗时 3 秒。

于 2020-11-12T20:36:02.587 回答
1

如果您有一个复杂的流程结构,并且您想要分析代码的特定部分,或者可能是流程的特定工作核心,您可以指向分析器以在那里收集统计信息(请参阅启用和禁用方法https://docs. python.org/3.6/library/profile.html#module-cProfile)。这是你可以做的:

import cProfile

def my_particular_worker_code()
    pr = cProfile.Profile()
    pr.enable()

    # Process stuff to be profiled

    pr.disable()
    pr.print_stats(sort='tottime')  # sort as you wish

您也可以将报告拖放到文件中。

于 2021-03-26T14:01:53.300 回答