потока, условно producer/consumer, общаются через очередь.
я хочу, чтобы при необрабатываемом падении одного из потоков автоматически и максимально быстро (т.е. не дожидаясь таймаута на очереди) падал второй, чтобы MainThread мог выйти. нужно для минимизации времени реакции саппорта на ошибку.
штатного способа прибить поток, как я понимаю, нет.
я сейчас передаю в оба потока threading.Event, который устанавливается падающим потоком, и проверяется обеими на каждой итерации. при event.is_set() == True корректно работающий поток тоже выходит, возвращая контроль MainThread, который уже решает, что с этим делать.
это адекватный подход?
альтернативу вижу в двух явных daemon thread (сейчас это ThreadPoolExecutor), состояние которых опрашивается из MainThread, и которые автоматичеки убиваются при выходе Main (для простоты предположим что вопрос корректности закрытия меня не интересует).
можно апнуть раз? спасибо
> я сейчас передаю в оба потока threading.Event, который устанавливается падающим потоком, и проверяется обеими на каждой итерации. при event.is_set() == True корректно работающий поток тоже выходит, возвращая контроль MainThread, который уже решает, что с этим делать. Да, мне кажется вполне. daemon thread я бы без явно выраженной необходимости не использовал бы.
> daemon thread я бы без явно выраженной необходимости не использовал бы. а почему нет?
и тут сразу второй вопрос. допустим, поток ждет Queue.get(timeout=x), x - десятки минут. проверить состояние Event он в этот момент не может. как его обрубить? я сейчас делаю цикл queue.get_nowait() + sleep() + event.is_set(). что работает, но некрасиво. daemon thread решил бы эту проблему, как я понимаю.
Как по-твоему работают daemon threads?
А зачем ты выставляешь такой огромный таймаут?
при выходе интерпретатора выключаются без выполнения кода, корректно освобождающего какие-то задействованные ресурсы. в моем конкретном случае, насколько я могу судить, это не является проблемой.
специфика бизнес-логики. подготовка одной задачи перед постановкой в очередь может занимать десятки минут.
э... ШТА? что мешает тебе иметь небольшой таймаут и проверять event?
ничего не мешает. я сейчас так и делаю, см. выше. в цикле: короткий таймаут + проверка очереди + проверка event + проверка, не вышли ли мы за разрешенный таймаут по сумме итераций. но я хотел чистый queue.get без вот этого всего, который бы убивался когда нужно. daemon решает эту задачу.
нет, ты зачем-то туда sleep всунул.
ну окей, слип всунул зря. суть не меняется.
суть очень сильно меняется. в общем ты можешь либо проверять состояние потоков из другого потока (main thread например) и выставлять событие если один из них завершился. либо же выставлять это событие внутри завершающегося потока. разница небольшая.
ок. почему суть меняется?
потому что в одном случае твой поток сидит и ждет непонятно чего, а во втором ждет конкретного события на очереди.
Обсуждают сегодня