Гонка потоков при использовании 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())
→ Ссылка