How do I run routines where timing is critical?

Jeff Epler jepler at unpythonic.net
Wed Jun 23 22:20:59 EDT 2004


IMO you want an event-driven structure.

    import heapq, math, time

    events = []

The event loop looks something like this: (all untested)
    def sleep_until(when):
        now = time.time()
        if when > now:
            time.sleep(when-now)

    def add_event(when, callback):
        heapq.heappush(events, (when, callback))

    def eventloop():
        while events:
            when, callback = heapq.heappop(events)
            sleep_until(when)
            callback()

A camera might be something like this: (again, all untested)
    class Camera:
        def __init__(self, number, frequency):
            self.number = number
            self.frequency = frequency
            self.reschedule()

        def __repr__(self):
            return "<Camera %d (frequency %d/sec)>" % (self.number, self.frequency)

        def take_photo(self):
            print "Taking photo from", self, "at", time.time() % 60

        def reschedule(self):
            now = time.time()
            f = self.frequency
            next = math.floor(now * f + 1) / f
            add_event(next, self.callback)

        def callback(self):
            self.take_photo()
            self.reschedule()

The main program would create 8 cameras and run the event loop:
    def main():
        frequency = [3, 3, 2, 2, 2, 2, 1, 1]
        cameras = [Camera(i, f) for (i, f) in enumerate(frequency)]
        eventloop()

    if __name__ == '__main__':
        main()

The calculation of the "next" in reschedule is intended to find the next
"1/frequency" time.  This means that if a camera has frequency=2, and
fires at time 1.6, it will next fire at time 2.0---even if the last time
it schedule itself, it was scheduled for time 1.0 and was delayed by 0.6
seconds.  I suspect that if the system can't keep up with all the
cameras, that this will result in the cameras being serviced
"round-robin" with equal frequency, which may or may not be acceptable.
It also means that after a temporary slowdown (background disk activity)
clears up, the cameras will immediately return to their given speed in
Hz, rather than trying to take the appropriate number of photos to the
number of seconds that have passed, in quick succession.

Jeff
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 196 bytes
Desc: not available
URL: <http://mail.python.org/pipermail/python-list/attachments/20040623/91726cc3/attachment.sig>


More information about the Python-list mailing list