Python多进程调试

时间:2012-06-19 17:14:55

标签: python debugging multiprocessing pycharm winpdb

我正在尝试调试一个简单的python应用程序但到目前为止没有运气。

import multiprocessing

def worker(num):
    for a in range(0, 10):
        print a

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

我想在for循环中设置一个断点来跟踪'a'的值,但是我试过的工具中没有这个值可以做到。 到目前为止,我尝试用以下方法进行调查:

  • PyCharm并收到以下错误:ImportError:没有名为的模块 pydevd - http://youtrack.jetbrains.com/issue/PY-6649看起来像 他们仍然正在努力解决这个问题,据我所知,这个没有ETA。
  • 我也试过使用Winpdb进行调试 - http://winpdb.org但是它根本不会进入我的'worker'方法而只打印'a'的值

我真的很感激任何帮助!

6 个答案:

答案 0 :(得分:2)

我在我的virtualenv中将/Applications/PyCharm\ 2.6\ EAP.app/helpers/pydev/*.py中的所有内容复制到site-packages并且它适用于我(我正在调试celery / kombu,断点按预期工作)。

答案 1 :(得分:2)

我发现在设置断点时用multiprocessing.Process()替换threading.Thread()非常有用。这两个类都有相似的参数,因此在大多数情况下它们是可以互换的。

通常,我的脚本使用Process()直到我指定命令行参数--debug为止,该参数有效地将这些调用替换为Thread()。这使我可以使用pdb调试这些脚本。

答案 2 :(得分:1)

如果常规的pdb / ipdb可用于多处理,那将是很好的。如果我可以逃脱它,如果配置的进程数为1,我会串行处理多处理调用。

if processes == 1:
    for record in data:
        worker_function(data)
else:
    pool.map(worker_function, data)

然后在调试时,将应用程序配置为仅使用单个进程。这并不包括所有情况,特别是在处理并发问题时,但它可能有所帮助。

答案 3 :(得分:0)

在尝试调试Python代码时,我很少需要使用传统的调试器,而是倾向于使用跟踪语句自由地散布我的代码。我将您的代码更改为以下内容:

import multiprocessing
import logging

def worker(num):
    for a in range(0, 10):
        logging.debug("(%d, %d)" % (num, a))

if __name__ == '__main__':
    logging.basicConfig(level=logging.DEBUG)
    for i in range(5):
        p = multiprocessing.Process(target=worker, args=(i,))
        logging.info("Starting process %d" % i)
        p.start()

在生产中,通过将跟踪级别设置为logging.WARNING来禁用调试跟踪语句,以便只记录警告和错误。

官方Python网站上有一个很好的basicadvanced日志教程。

答案 4 :(得分:0)

WingIDE Pro提供即开即用的此功能。

不需要额外的代码(例如,使用traceback模块)。您只需运行您的程序,Wing调试器不仅会从子进程中打印stdout,而且会在子进程中出现错误并且立即创建和交互式shell,以便您可以调试有问题的线程。它没有比这更容易,我知道没有其他IDE以这种方式暴露子进程。

是的,它是商业产品。但我还没有找到任何其他IDE提供匹配的调试器。 PyCharm Professional,Visual Studio社区,Komodo IDE - 我已经尝试过所有这些。在我看来,WingIDE也在解析源文档方面处于领先地位。眼睛舒适绿色配色是我现在没有的生活方式。

(是的,我知道这个问题已经超过5年了。无论如何我都会回答。)

答案 5 :(得分:0)

您应该可以使用remote-pdb做到这一点。

from multiprocessing import Pool


def test(thing):
  from remote_pdb import set_trace
  set_trace()
  s = thing*2
  print(s)
  return s



if __name__ == '__main__':
  with Pool(5) as p:
    print(p.map(test,['dog','cat','bird']))

然后只需telnet到日志中列出的端口。

示例:

RemotePdb session open at 127.0.0.1:54273, waiting for connection ...
telnet 127.0.0.1 54273
<telnet junk>
-> s = thing*2
(Pdb) 

nc -tC 127.0.0.1 54273

-> s = thing * 2
(Pdb)

您应该能够在那时调试该过程。