输入pdb时,有什么方法可以停止后台进程?

时间:2019-04-26 19:52:52

标签: python-2.7 python-multithreading pdb gdb-python

所以,我有一些这样的代码:

class ProgressProc(multiprocessing.Process):
    def __init__(self):
        multiprocessing.Process.__init__(self)

    def run(self):
        while True:
            markProgress()
            time.sleep(10)

progressProc = ProgressProc()
progressProc.start()
doSomething()
progressProc.terminate()

问题是,如果我在doSomething()函数中执行pdb.set_trace(),ProgressProc进程将继续进行。当pdb提示符处于活动状态时,它将始终将内容打印到控制台。我想为ProgressProc提供某种方法来检查主线程(实际上是任何其他线程)是否在pdb中挂起,然后我可以跳过markProgress()。

有sys.gettrace(),但这仅适用于执行pdb.set_trace()的线程,我不知道如何在与我所在的线程不同的线程上调用它。我可不可以做?有什么可以捕捉到的信号吗?我可以用我的主要方法替换pdb.set_trace来先调用一些multiprocessing.Event。有没有更清洁的方法?

ETA:这也适用于python gdb命令。

1 个答案:

答案 0 :(得分:0)

Pdb当前无法使用多个线程或进程进行调试。但是,希望以下内容对您有所帮助。

此解决方案通过Pdb挂起主线程,然后向启动Rpdb的另一个进程发送信号。

在运行中打开套接字。确保将超时设置为0。当进程接收到信号时,请使用rpdb.set_trace()启动Rpdb。

signal = 'break'
address = ('localhost', 6000)

def run(self):
    listener = Listener(address=address)
    listener._listener._socket.settimeout(0)
    recvd = False
    while True:
        markProgress()
        if not recvd:
            try:
                conn = listener.accept()
                msg = conn.recv()
                if msg == signal:
                    recvd = True
                    rpdb.set_trace()
            except:
                pass
        time.sleep(2)

像以前一样在set_trace()内进行doSomething(),然后连接到插座并发送信号。

def doSomething():
    pdb.set_trace()
    conn = Client(address)
    conn.send(signal)
    conn.close()
    for x in range(100):
        time.sleep(1)
        sys.__stdout__.write("doSomething: " + str(x) + "\n")

现在您可以启动程序了。发送信号后,您应该获得输出pdb is running on 127.0.0.1:4444。现在打开第二个终端,并使用nc localhost 4444连接到Rpdb。

  • 这仅适用于两个进程/线程。如果您想使用更多功能,则可以尝试为每个进程使用不同的端口启动Rpdb,例如:rpdb.Rpdb(port=12345)
  • 您可能必须将所有print更改为sys.__stdout__.write,因为Rpdb更改了stdout。