Поймайте исключение потока в потоке вызывающей стороны в Python

Я очень плохо знаком с Python и многопоточным программированием в целом. В основном у меня есть сценарий, который скопирует файлы в другое местоположение. Я хотел бы, чтобы это было помещено в другой поток, таким образом, я могу произвести .... указать, что сценарий все еще работает.

Проблема, которую я имею, состоит в том, что, если файлы не могут быть скопированы, это выдаст исключение. Это в порядке при выполнении в основном потоке; однако, наличие следующего кода не работает:

try:
    threadClass = TheThread(param1, param2, etc.)
    threadClass.start()   ##### **Exception takes place here**
except:
    print "Caught an exception"

В самом классе потока я пытался повторно бросить исключение, но это не работает. Я видел, что люди на здесь задают подобные вопросы, но они все, кажется, делают что-то более определенное, чем, что я пытаюсь сделать (и я не вполне понимаю предлагаемых решений). Я видел, что люди упоминают использование sys.exc_info(), однако я не знаю, где или как использовать его.

Вся справка значительно ценится!

Править: Код для класса потока ниже:

class TheThread(threading.Thread):
    def __init__(self, sourceFolder, destFolder):
        threading.Thread.__init__(self)
        self.sourceFolder = sourceFolder
        self.destFolder = destFolder

    def run(self):
        try:
           shul.copytree(self.sourceFolder, self.destFolder)
        except:
           raise
176
задан 5 revs 20 June 2010 в 02:56
поделиться

2 ответа

Проблема в том, что thread_obj.start () возвращается немедленно. Дочерний поток, который вы создали, выполняется в собственном контексте со своим собственным стеком. Любое возникающее исключение существует в контексте дочернего потока и находится в его собственном стеке. Один из способов, который я могу придумать прямо сейчас, передать эту информацию родительскому потоку, - это использовать какой-то тип передачи сообщений, так что вы можете изучить это.

Примерьте это на размер:

import sys
import threading
import Queue


class ExcThread(threading.Thread):

    def __init__(self, bucket):
        threading.Thread.__init__(self)
        self.bucket = bucket

    def run(self):
        try:
            raise Exception('An error occured here.')
        except Exception:
            self.bucket.put(sys.exc_info())


def main():
    bucket = Queue.Queue()
    thread_obj = ExcThread(bucket)
    thread_obj.start()

    while True:
        try:
            exc = bucket.get(block=False)
        except Queue.Empty:
            pass
        else:
            exc_type, exc_obj, exc_trace = exc
            # deal with the exception
            print exc_type, exc_obj
            print exc_trace

        thread_obj.join(0.1)
        if thread_obj.isAlive():
            continue
        else:
            break


if __name__ == '__main__':
    main()
104
ответ дан 23 November 2019 в 20:23
поделиться

Использование открытых исключений - не лучшая практика, потому что обычно вы ловите больше, чем рассчитываете.

Я бы предложил изменить за исключением , чтобы перехватить ТОЛЬКО исключение, которое вы хотите обработать. Я не думаю, что его повышение имеет желаемый эффект, потому что, когда вы переходите к созданию экземпляра TheThread во внешнем , попробуйте , если оно вызывает исключение, присвоение никогда не произойдет. .

Вместо этого вы можете просто предупредить об этом и двигаться дальше, например:

def run(self):
    try:
       shul.copytree(self.sourceFolder, self.destFolder)
    except OSError, err:
       print err

Затем, когда это исключение будет обнаружено, вы можете обработать его там. Затем, когда внешний try перехватывает исключение из TheThread , вы знаете, что это не будет тот, который вы уже обработали, и поможет вам изолировать поток вашего процесса.

0
ответ дан 23 November 2019 в 20:23
поделиться
Другие вопросы по тегам:

Похожие вопросы: