如何独立调试Python线程?(WinPDB)
我正在用WinPDB调试Python程序,里面有多个线程是通过threading.Thread创建的。可我总是无法单独控制这些线程。如果我中断执行,整个脚本都会停止。如果我在一个线程的源代码中逐步调试,其他线程却会继续执行,互相交错。这种情况在同步功能开启或关闭时都是如此。难道没有办法在保持其他线程在断点的情况下,单独逐步调试一个线程吗?
使用WinPDB是不是不太合适?我真的不知道该用什么工具。Eclipse的PyDev几乎完全无法使用,因为调试器在启动多个线程时似乎会出现竞争错误。
有没有什么工具可以真正有效地调试一个多线程的Python程序?
谢谢。
1 个回答
1
我遇到过类似的问题,这不是最理想的解决办法,但我可以给你描述一下,也许你能从中得到一些启发。
我大致上写了一个迷你调试器。它包含了一个UDP客户端和服务器,还有一个函数,这个函数的作用就是获取一个全局锁,暂停0.1秒,然后再释放这个锁。这个函数被传递给每个线程。然后我在我想要调试的关键区域之间调用这个函数。启动程序后,UDP服务器会监听客户端,如果我输入“pause”,它就会获取那个共享函数使用的全局锁,并且在我输入“play”之前不会释放这个锁。通过这种方式,你可以在应用程序中实现比较精确的暂停……这取决于具体的应用。
希望这对你有帮助……下面是一个小片段。我的应用是为了测试平台,所以我在基类构造函数中添加了这个函数指针,使用它代替了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()