Для какой-то части моего проекта мне нужна система локального планирования процессов, которая позволит мне отложить выполнение метода на несколько секунд. У меня есть тысячи «клиентов» этой системы, поэтому использование threading.Timer
для каждой задержки - плохая идея, потому что я быстро достигну предела потока ОС. Я реализовал систему, которая использует только один поток для контроля времени.
Основная идея состоит в том, чтобы сохранить отсортированную очередь задач (time + func + args + kwargs) и использовать одну threading.Timer
для планирования / отмены выполнения заголовка этой очереди. Эта схема работает, но я не доволен производительностью. ~ 2000 клиентов, которые планируют фиктивные задачи каждые ~ 10 секунд, заставляют процесс занимать 40% процессорного времени. Глядя на вывод профилировщика, я вижу, что все время тратится на создание новой threading.Timer
s, ее запуск и особенно на создание новых потоков.
Я считаю, что есть лучший способ. Теперь я думаю о переписывании LightTimer
, чтобы был один поток выполнения, управляемый threading.Event
, и несколько потоков синхронизации, которые будут set()
событие. Например:
- Я планирую задачу для вызова через 10 секунд. Задача добавлена в очередь. Сроки # 1 начинается
time.sleep(10)
до event.set()
- Затем я планирую задачу для вызова через 11 секунд. Задача добавлена в очередь. Ничего не происходит с потоком синхронизации, он обнаружит новую задачу после пробуждения.
- Затем я планирую задачу для вызова через 5 секунд. Задача добавляется в очередь. Временной поток № 2 начинается
time.sleep(5)
, потому что # 1 уже спит в течение более длительного интервала.
Надеюсь, вы уловили эту идею. Что вы думаете об этом пути? Есть ли способ лучше? Может быть, я могу использовать некоторые функции системы Linux, чтобы найти оптимальное решение?