Вопрос (а):
Это зависит.Если вам нужно запустить process_user_dict
более одного раза, то имеет смысл запустить пул в конструкторе и продолжить его работу.Создание пула потоков всегда сопряжено с некоторыми издержками, и, поддерживая пул между вызовами на process_user_dict
, вы избежите этих дополнительных издержек.
Если вы просто хотите обработать один набор входных данных, вы также можете создатьваш бассейн прямо внутри process_user_dict
.Но, вероятно, не прямо перед results = self.pool.map(self.predict_memcache, user_dicts)
, потому что это создаст пул для каждой итерации окружающего цикла while
.
В вашем конкретном случае это не имеет никакого значения.Вы создаете свой TSNew_
объект на уровне модуля, чтобы он оставался живым (и вместе с ним пул потоков), пока ваше приложение работает;один и тот же пул потоков из того же экземпляра TSNew
используется для обработки всех запросов в течение времени жизни app.run()
.Поскольку вы, кажется, используете эту конструкцию с self.process = threading.Thread(target=self.process_user_dict)
в качестве своего рода слушателя на self.memory
, создание пула в конструкторе функционально эквивалентно созданию пула внутри process_user_dict
(но вне цикла).
Вопрос (b):
Технически, по умолчанию не существует скрытой ошибки при создании потока внутри потока.В конце концов, конечным родителем любого дополнительного потока всегда является MainThread
, который неявно создается для каждого экземпляра интерпретатора Python.По сути, каждый раз, когда вы создаете поток внутри программы Python, вы создаете поток в потоке.
На самом деле, ваш код даже не создает поток внутри потока.Ваш self.pool
создан внутри MainThread
.Когда пул создается с помощью self.pool = ThreadPool(40)
, он создает желаемое количество (40) рабочих потоков, плюс один поток рабочего обработчика, один поток обработчика задач и один поток обработчика результатов.Все это дочерние потоки MainThread
.Все, что вы делаете в отношении своего пула в потоке под self.process
, вызывает его метод map
для назначения ему задач.
Однако я не очень понимаю, что вы делаете с этимself.process
здесь.Делая предположение, я бы сказал, что вы хотите запустить цикл в process_user_dict
, чтобы он действовал как * слушатель на self.memory
, так что пул начинает обрабатывать user_dict
, как только они начинают появляться в deque
в self.memory
.Из того, что я вижу, что вы делаете в get_user_result
, вы, похоже, получаете один user_dict
за запрос.Я понимаю, что у вас могут быть параллельные пользовательские сессии, проходящие в этих диктовках, но действительно ли вы видите, что benfit из process_user_dict
работает в бесконечном цикле по сравнению с простым вызовом TSNew_.process_user_dict()
после TSNew_.memory.append(user_dict)
?Вы можете даже полностью пропустить self.memory
и передать диктант непосредственно process_user_dict
, если я не пропущу то, что вы нам не показали.