Гонка потоков при использовании schedule с разными потоками
В одном из своих проектов заметил проблему с schedule:
- У меня есть несколько функций, которые выполняются в отдельных потоках и по расписанию (время разное)
- Но заметил, что одна из функций вызывалась два раза и одновременно
Накидал минимальный пример и проблема подтвердилась. Вызов функций действительно дублируется
Пример:
import threading
import time
import schedule
def run1():
print('run1', threading.current_thread())
time.sleep(2)
def run2():
print('run2', threading.current_thread())
time.sleep(3)
def run_schedule(timeout, run):
schedule.every(timeout).seconds.do(run)
while True:
schedule.run_pending()
time.sleep(1)
threading.Thread(target=run_schedule, args=[5, run1]).start()
threading.Thread(target=run_schedule, args=[7, run2]).start()
Вывод:
run1 run1 <Thread(Thread-1, started 17828)>
<Thread(Thread-2, started 14008)>
run2 <Thread(Thread-2, started 14008)>
run2 <Thread(Thread-1, started 17828)>
Как видно, функции вызываются по одному разу на каждый поток, что вызывает run_pending
Ответы (1 шт):
Автор решения: gil9red
→ Ссылка
Решением будет создавать отдельные schedule для разных потоков.
Достаточно поменять функцию:
def run_schedule(timeout, run):
scheduler = schedule.Scheduler()
scheduler.every(timeout).seconds.do(run)
while True:
scheduler.run_pending()
time.sleep(1)
PS.
Думаю, и выделение отдельного потока для цикла с schedule.run_pending() тоже сработало бы, а чтобы функции выполнялись в отдельных потоках нужно бы в .do(run) оборачивать код в поток, типа:
scheduler.every(timeout).seconds.do(lambda: Thread(target=run).start())