Threading#
The Scheduler
is thread safe and supports parallel execution
of pending Job
s.
Job
s with a relevant execution time or blocking IO operations
can delay each other.
Warning
When running Job
s in parallel, be sure that possible side effects
of the scheduled functions are implemented in a thread safe manner.
The following examples show the difference between concurrent and parallel
Scheduler
s:
Concurrent execution#
By default the Scheduler
will execute its
Job
s sequentially. The total duration when executing multiple
Job
s will therefore be greater than the sum of the individual
run times.
>>> import datetime as dt
>>> import time
>>> from scheduler import Scheduler
>>> def sleep(secs: float):
... time.sleep(secs)
...
>>> schedule = Scheduler()
>>> job_1 = schedule.once(dt.timedelta(), sleep, kwargs={"secs": 0.1})
>>> job_2 = schedule.once(dt.timedelta(), sleep, kwargs={"secs": 0.1})
>>> start_time = time.perf_counter()
>>> n_exec = schedule.exec_jobs()
>>> total_seconds = time.perf_counter() - start_time
>>> n_exec
2
>>> 0.2 < total_seconds and total_seconds < 0.21
True
Parallel execution#
The number of worker threads for the Scheduler
can be defined
with the n_threads argument. For n_threads = 0
the Scheduler
will spawn a seperate worker thread for every pending Job
.
>>> import datetime as dt
>>> import time
>>> from scheduler import Scheduler
>>> def sleep(secs: float):
... time.sleep(secs)
...
>>> schedule = Scheduler(n_threads=0)
>>> job_1 = schedule.once(dt.timedelta(), sleep, kwargs={"secs": 0.1})
>>> job_2 = schedule.once(dt.timedelta(), sleep, kwargs={"secs": 0.1})
>>> start_time = time.perf_counter()
>>> n_exec = schedule.exec_jobs()
>>> total_seconds = time.perf_counter() - start_time
>>> n_exec
2
>>> 0.1 < total_seconds and total_seconds < 0.11
True