【问题标题】:Recommendations for workflow when debugging Python scripts employing multiprocessing?调试使用多处理的 Python 脚本时的工作流建议?
【发布时间】:2014-05-26 21:57:28
【问题描述】:

我使用 Spyder IDE。通常,当我运行非并行脚本时,我倾向于使用print 语句进行调试。根据打印(或不打印)哪些语句,我可以看到发生错误的位置。

例如:

print "Started while loop..."
doWhileLoop = False
while doWhileLoop == True:
    print "Doing something important!"
    time.sleep(5)
print "Finished while loop..."

在上面,我错过了在某些时候将 doWhileLoop 更改为 False 的行,所以我将永远卡在 while 循环中,但我的 print 语句让我看到它在我的代码中的位置我挂了。

但是,当运行并行化的脚本时,直到进程完成后,我才能得到控制台的输出。通常,我在这种情况下所做的是尝试使用单个进程进行调试(例如,通过仅运行一个任务来临时取消程序的并行性),但目前,我正在处理一个似乎仅发生的错误 当我运行多个任务时。

所以,我无法使用我常用的方法弄清楚这个错误是什么——我应该如何改变我通常的调试实践,以便有效地调试使用多处理的脚本?

【问题讨论】:

  • 调试并行的东西很难。您只需要根据具体情况进行操作即可。至于您的 print 语句在过程完成之前不会打印,这可能是 Spyder 做了一些不会发生的 stdout 缓冲。您可以在每个打印语句之后执行sys.stdout.flush(),或使用不同的环境。

标签: debugging python-2.7 multiprocessing


【解决方案1】:

就像@roippi 所说,调试并行的东西很难。另一个工具是使用logging 而不是print。日志记录为您提供严重性、时间戳以及最重要的哪个进程正在做某事。

示例代码:

import logging, multiprocessing, Queue

def myproc(arg):
    return arg*2

def worker(inqueue, outqueue):
    mylog = multiprocessing.get_logger()
    mylog.info('start')
    for job in iter(inqueue.get, 'STOP'):
        mylog.info('got %s', job)
        try:
            outqueue.put( myproc(job), timeout=1 )
        except Queue.Full:
            mylog.error('queue full!')

    mylog.info('done')

def executive(inqueue):
    total = 0
    mylog = multiprocessing.get_logger()
    for num in iter(inqueue.get, 'STOP'):
        total += num
        mylog.info('got {}\ttotal{}', job, total)

logger = multiprocessing.log_to_stderr(
    level=logging.INFO,
)
logger.info('setup')

inqueue, outqueue = multiprocessing.Queue(), multiprocessing.Queue()
if 0:                           # debug 'queue full!' issues
    outqueue = multiprocessing.Queue(maxsize=1)
# prefill with 3 jobs
for num in range(3):
    inqueue.put(num)
# signal end of jobs
inqueue.put('STOP')

worker_p = multiprocessing.Process(
    target=worker, args=(inqueue, outqueue),
    name='worker',
)
worker_p.start()

worker_p.join()

logger.info('done')

示例输出:

[INFO/MainProcess] setup
[INFO/worker] child process calling self.run()
[INFO/worker] start
[INFO/worker] got 0
[INFO/worker] got 1
[INFO/worker] got 2
[INFO/worker] done
[INFO/worker] process shutting down
[INFO/worker] process exiting with exitcode 0
[INFO/MainProcess] done
[INFO/MainProcess] process shutting down

【讨论】:

    猜你喜欢
    • 2012-10-22
    • 2017-06-13
    • 2019-07-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-28
    • 2010-10-03
    相关资源
    最近更新 更多