Как я могу гарантировать, что зависший поток в конечном итоге будет собирать мусор в Python

У меня есть долго работающая программа, которая периодически подключается к внешним сетевым ресурсам. Я завернул эти вызовы в поток тайм-аута, поэтому, если вызов занимает более 10 секунд, вызов немедленно возвращает ошибку, например:

def fetch_resource(url):
    class TimeoutThread(Thread):
        def __init__(self):
            Thread.__init__(self)
            self.result = None

        def run(self):
            self.result = requests.get(url)

    tt = TimeoutThread()
    tt.start()
    tt.join(10.0)
    if tt.result:
        return tt.result.content
    else:
        return None

Однако, читая документацию Thread, кажется, что Thread.join() вернет либо:

  1. Когда поток завершается или
  2. через 10 секунд

В случае, когда .join() возвращается через 10 секунд, поток все еще жив, верно? Я понимаю, что нет хороших способов убить поток, но как я могу гарантировать, что поток в конечном итоге завершится и будет собран мусор? Я беспокоюсь, что потоки могут зависнуть и никогда не вернуться, таким образом, постепенно съедая ресурсы, которые никогда не освобождаются.


person Chris B.    schedule 02.02.2012    source источник
comment
Если у вас есть длинный поток, он, вероятно, работает внутри какого-то цикла, верно? Добавьте проверку внутри этого цикла, что если для self.__quit, например, установлено значение True, вы выходите из цикла. Вы можете перезаписать метод соединения потока, чтобы установить для self.__quit значение True, завершая цикл и выполнение потока.   -  person Luiz C.    schedule 03.02.2012
comment
Потенциально долгим потоком является self.result = requests.get(url). Так что нет, дело не в цикле.   -  person Chris B.    schedule 03.02.2012
comment
Тогда я полагаю, что в конечном итоге это будет зависеть от логики внутри request.get(url). Что он делает?   -  person jdi    schedule 03.02.2012
comment
Выполнение сетевого вызова по URL-адресу   -  person Chris B.    schedule 03.02.2012
comment
Не может ли истечь время сетевого вызова? В противном случае проверьте это: stackoverflow.com/questions/323972/   -  person jdi    schedule 03.02.2012


Ответы (1)


Я не знаю, почему вы возитесь с отдельным потоком, учитывая, что ваш основной поток заблокирован во время ожидания завершения запроса или истечения времени ожидания. Почему бы просто не установить тайм-аут запроса?

Обратите внимание, что вы можете вызвать Socket.setdefaulttimeout, чтобы установить время ожидания по умолчанию. на объектах Socket, созданных с этого момента, например. в библиотеках, которые сами по себе не дают возможности указать время ожидания запроса.

person Lawrence D'Oliveiro    schedule 02.02.2012