Georg Brandl | 116aa62 | 2007-08-15 14:28:22 +0000 | [diff] [blame] | 1 | :mod:`sched` --- Event scheduler |
| 2 | ================================ |
| 3 | |
| 4 | .. module:: sched |
| 5 | :synopsis: General purpose event scheduler. |
| 6 | .. sectionauthor:: Moshe Zadka <moshez@zadka.site.co.il> |
| 7 | |
Georg Brandl | 116aa62 | 2007-08-15 14:28:22 +0000 | [diff] [blame] | 8 | .. index:: single: event scheduling |
| 9 | |
| 10 | The :mod:`sched` module defines a class which implements a general purpose event |
| 11 | scheduler: |
| 12 | |
| 13 | |
| 14 | .. class:: scheduler(timefunc, delayfunc) |
| 15 | |
| 16 | The :class:`scheduler` class defines a generic interface to scheduling events. |
| 17 | It needs two functions to actually deal with the "outside world" --- *timefunc* |
| 18 | should be callable without arguments, and return a number (the "time", in any |
| 19 | units whatsoever). The *delayfunc* function should be callable with one |
| 20 | argument, compatible with the output of *timefunc*, and should delay that many |
| 21 | time units. *delayfunc* will also be called with the argument ``0`` after each |
| 22 | event is run to allow other threads an opportunity to run in multi-threaded |
| 23 | applications. |
| 24 | |
| 25 | Example:: |
| 26 | |
| 27 | >>> import sched, time |
Christian Heimes | fe337bf | 2008-03-23 21:54:12 +0000 | [diff] [blame] | 28 | >>> s = sched.scheduler(time.time, time.sleep) |
Georg Brandl | 6911e3c | 2007-09-04 07:15:32 +0000 | [diff] [blame] | 29 | >>> def print_time(): print("From print_time", time.time()) |
Georg Brandl | 116aa62 | 2007-08-15 14:28:22 +0000 | [diff] [blame] | 30 | ... |
| 31 | >>> def print_some_times(): |
Georg Brandl | 6911e3c | 2007-09-04 07:15:32 +0000 | [diff] [blame] | 32 | ... print(time.time()) |
Georg Brandl | 116aa62 | 2007-08-15 14:28:22 +0000 | [diff] [blame] | 33 | ... s.enter(5, 1, print_time, ()) |
| 34 | ... s.enter(10, 1, print_time, ()) |
| 35 | ... s.run() |
Georg Brandl | 6911e3c | 2007-09-04 07:15:32 +0000 | [diff] [blame] | 36 | ... print(time.time()) |
Georg Brandl | 116aa62 | 2007-08-15 14:28:22 +0000 | [diff] [blame] | 37 | ... |
| 38 | >>> print_some_times() |
| 39 | 930343690.257 |
| 40 | From print_time 930343695.274 |
| 41 | From print_time 930343700.273 |
| 42 | 930343700.276 |
| 43 | |
Christian Heimes | 679db4a | 2008-01-18 09:56:22 +0000 | [diff] [blame] | 44 | In multi-threaded environments, the :class:`scheduler` class has limitations |
Georg Brandl | 48310cd | 2009-01-03 21:18:54 +0000 | [diff] [blame] | 45 | with respect to thread-safety, inability to insert a new task before |
Christian Heimes | 679db4a | 2008-01-18 09:56:22 +0000 | [diff] [blame] | 46 | the one currently pending in a running scheduler, and holding up the main |
| 47 | thread until the event queue is empty. Instead, the preferred approach |
| 48 | is to use the :class:`threading.Timer` class instead. |
| 49 | |
| 50 | Example:: |
| 51 | |
| 52 | >>> import time |
| 53 | >>> from threading import Timer |
| 54 | >>> def print_time(): |
Neal Norwitz | 752abd0 | 2008-05-13 04:55:24 +0000 | [diff] [blame] | 55 | ... print("From print_time", time.time()) |
Christian Heimes | 679db4a | 2008-01-18 09:56:22 +0000 | [diff] [blame] | 56 | ... |
| 57 | >>> def print_some_times(): |
Neal Norwitz | 752abd0 | 2008-05-13 04:55:24 +0000 | [diff] [blame] | 58 | ... print(time.time()) |
Christian Heimes | 679db4a | 2008-01-18 09:56:22 +0000 | [diff] [blame] | 59 | ... Timer(5, print_time, ()).start() |
| 60 | ... Timer(10, print_time, ()).start() |
Georg Brandl | a1c6a1c | 2009-01-03 21:26:05 +0000 | [diff] [blame^] | 61 | ... time.sleep(11) # sleep while time-delay events execute |
Neal Norwitz | 752abd0 | 2008-05-13 04:55:24 +0000 | [diff] [blame] | 62 | ... print(time.time()) |
Christian Heimes | 679db4a | 2008-01-18 09:56:22 +0000 | [diff] [blame] | 63 | ... |
| 64 | >>> print_some_times() |
| 65 | 930343690.257 |
| 66 | From print_time 930343695.274 |
| 67 | From print_time 930343700.273 |
| 68 | 930343701.301 |
| 69 | |
Georg Brandl | 116aa62 | 2007-08-15 14:28:22 +0000 | [diff] [blame] | 70 | |
| 71 | .. _scheduler-objects: |
| 72 | |
| 73 | Scheduler Objects |
| 74 | ----------------- |
| 75 | |
Christian Heimes | 679db4a | 2008-01-18 09:56:22 +0000 | [diff] [blame] | 76 | :class:`scheduler` instances have the following methods and attributes: |
Georg Brandl | 116aa62 | 2007-08-15 14:28:22 +0000 | [diff] [blame] | 77 | |
| 78 | |
| 79 | .. method:: scheduler.enterabs(time, priority, action, argument) |
| 80 | |
| 81 | Schedule a new event. The *time* argument should be a numeric type compatible |
| 82 | with the return value of the *timefunc* function passed to the constructor. |
| 83 | Events scheduled for the same *time* will be executed in the order of their |
| 84 | *priority*. |
| 85 | |
| 86 | Executing the event means executing ``action(*argument)``. *argument* must be a |
| 87 | sequence holding the parameters for *action*. |
| 88 | |
| 89 | Return value is an event which may be used for later cancellation of the event |
| 90 | (see :meth:`cancel`). |
| 91 | |
| 92 | |
| 93 | .. method:: scheduler.enter(delay, priority, action, argument) |
| 94 | |
| 95 | Schedule an event for *delay* more time units. Other then the relative time, the |
| 96 | other arguments, the effect and the return value are the same as those for |
| 97 | :meth:`enterabs`. |
| 98 | |
| 99 | |
| 100 | .. method:: scheduler.cancel(event) |
| 101 | |
| 102 | Remove the event from the queue. If *event* is not an event currently in the |
| 103 | queue, this method will raise a :exc:`RuntimeError`. |
| 104 | |
| 105 | |
| 106 | .. method:: scheduler.empty() |
| 107 | |
| 108 | Return true if the event queue is empty. |
| 109 | |
| 110 | |
| 111 | .. method:: scheduler.run() |
| 112 | |
| 113 | Run all scheduled events. This function will wait (using the :func:`delayfunc` |
| 114 | function passed to the constructor) for the next event, then execute it and so |
| 115 | on until there are no more scheduled events. |
| 116 | |
| 117 | Either *action* or *delayfunc* can raise an exception. In either case, the |
| 118 | scheduler will maintain a consistent state and propagate the exception. If an |
| 119 | exception is raised by *action*, the event will not be attempted in future calls |
| 120 | to :meth:`run`. |
| 121 | |
| 122 | If a sequence of events takes longer to run than the time available before the |
| 123 | next event, the scheduler will simply fall behind. No events will be dropped; |
| 124 | the calling code is responsible for canceling events which are no longer |
| 125 | pertinent. |
| 126 | |
Christian Heimes | 679db4a | 2008-01-18 09:56:22 +0000 | [diff] [blame] | 127 | .. attribute:: scheduler.queue |
| 128 | |
| 129 | Read-only attribute returning a list of upcoming events in the order they |
| 130 | will be run. Each event is shown as a :term:`named tuple` with the |
| 131 | following fields: time, priority, action, argument. |