Есть ли способ остановить фоновый процесс при вводе pdb? - PullRequest
1 голос
/ 26 апреля 2019

Итак, у меня есть такой код:

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()

Проблема в том, что если я выполняю pdb.set_trace () внутри функции doSomething (), процесс ProgressProc продолжает работать. Он продолжает печатать данные на консоль, пока активно приглашение pdb. Я хотел бы, чтобы ProgressProc мог как-то проверить, приостановлен ли основной поток (на самом деле, любой другой поток) в pdb, и тогда я могу пропустить markProgress ().

Есть sys.gettrace (), но он работает только для потока, который сделал pdb.set_trace (), и я не могу понять, как вызвать его в другом потоке, чем тот, в котором я нахожусь. Что еще я могу сделать? Есть ли какие-нибудь сигналы, которые я могу поймать? Мой основной метод мог бы заменить pdb.set_trace, чтобы сначала вызвать несколько процессов. Есть ли способ чище?

ETA: это также для команды Python GDB.

1 Ответ

0 голосов
/ 08 мая 2019

Отладка с несколькими потоками или процессами в настоящее время невозможна с Pdb. Тем не менее, я надеюсь, что следующее может помочь вам.

Это решение приостанавливает основной поток с помощью Pdb, а затем отправляет сигнал другому процессу, в котором запускается Rpdb .

Открыть сокет в бегах. Обязательно установите время ожидания равным 0. Когда процесс получит сигнал, запустите Rpdb с rpdb.set_trace().

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. Теперь откройте второй терминал и подключитесь к Rpdb с помощью nc localhost 4444.

  • Это работает только с двумя процессами / потоками. Если вы хотите работать с большим количеством, вы можете попробовать запустить Rpdb с другим портом для каждого процесса, например: rpdb.Rpdb(port=12345)
  • Возможно, вам придется изменить все ваши print s на sys.__stdout__.write, потому что Rpdb меняет стандартный вывод.
...