【问题标题】:How to step through Python threads independently? (WinPDB)如何独立地单步执行 Python 线程? (WinPDB)
【发布时间】:2011-03-25 22:29:49
【问题描述】:

我正在尝试使用 WinPDB 调试 Python,并且我有多个使用 threading.Thread 的线程。我似乎永远无法单独控制线程。如果我中断执行,整个脚本都会中断。如果我单步执行一个线程的源代码,所有其他线程将继续交错并继续执行其中的一些。同步性打开或关闭时都是如此。有没有办法单独单步执行一个线程,同时保持其他线程处于断点?

WinPDB 是不是用错了工具?我只是不知道该用什么。 Eclipse PyDev 几乎无法运行,因为调试器本身在启动多个线程时似乎会出现竞争错误。

什么是真正强大调试多线程 Python 程序的工具?

谢谢。

【问题讨论】:

  • pdb 不支持调试多线程程序。不过,这应该适用于 PyDev。您遇到了什么问题?

标签: python multithreading debugging winpdb


【解决方案1】:

我有一个类似的问题,这不是最理想的答案,但我会为你描述它,也许你可以解决它。

我或多或少写了一个迷你调试器。 Udp 客户端/服务器和一个除了获取全局锁之外什么都不做的函数,休眠 0.1 秒,然后释放它。这个函数被传递给每个线程。然后,我在要调试的关键区域之间调用此函数。启动程序后,udp 服务器会监听客户端,如果我输入“暂停”,它会获取共享函数使用的相同全局锁,并且在我在客户端输入“播放”之前不会放弃它。所以这样做,你可以得到一个相当紧的停止......取决于应用程序。

希望对您有所帮助...下面的小sn-p。我的应用程序是用于测试平台的,所以我所做的是将函数指针添加到基类构造函数,并使用它而不是 time.sleep() .. 给我温和的可调试性。您可以做的是将它传递给每个线程,并在函数的开头和结尾添加对暂停函数的调用,这将允许您中断等。我删除了一些命令,但您可以看到这可以根据您的需要进行扩展。

PAUSE_NOW     = thread.allocate_lock()
def pause(s):
'''
    FUNCTION: testStatus

    DESCRIPTION: function passed to all test objects

    INPUTS: none

    RETURNS: none
'''
    global Pause_NOW
    PAUSE_NOW.acquire()
    time.sleep(s)
    PAUSE_NOW.release()

`

def server():
    '''
        \r\n
        FUNCTION: server

        DESCRIPTION: UDP server that launches a UDP client. The client it
                     starts can issue commands defined in cmdlineop. Most
                     functions return a status, but some are meant to block
                     the main thread as a means of pausing a test, in which case
                     a default response is returned.

        INPUTS: none

        RETURNS: none
    '''
    global EXIT
    global Pause_NOW

    host = "localhost"
    port = 21567
    buf  = 1024
    addr = (host,port)

    UDPSock = socket(AF_INET,SOCK_DGRAM)
    UDPSock.bind(addr)
    sleep(1)
    os.startfile('client.py')
    #os.system('start python client.py')
    cmdlineop   =   {
                    'pausenow' : "PAUSE_NOW.acquire()",
                    'playnow'  : "PAUSE_NOW.release()",
                }
    while 1:
        output = 'RECEIVED CMD'
        # if EXIT: break
        data,addr = UDPSock.recvfrom(buf)
        if not data:
            break
        else:
            if cmdlineop.has_key(data.split()[0]):
                exec(cmdlineop[(data.split()[0])])
                UDPSock.sendto(('\n'+output+'\n'),addr)
                data = ''
            else:
                UDPSock.sendto('INVALID CMD',addr)
    UDPSock.close()

【讨论】:

  • 我不完全理解第一个回答者对这个 UDP 客户端/服务器做了什么。 PyDev 不起作用,因为它使用一些 XML 文件得到这些奇怪的错误,调试器试图用状态信息写入这些文件。也许它有多个线程在运行多线程程序时尝试同时写入文件,并且没有设置为处理。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-04-14
  • 1970-01-01
  • 1970-01-01
  • 2018-04-08
  • 1970-01-01
  • 1970-01-01
  • 2017-09-14
相关资源
最近更新 更多