[Python编程(第4版)].(Programming.Python.4th.Edition).Mark.Lutz.文字版

(yzsuai) #1

Chapter 9, the thread queue tools implemented in Chapter 10, and the PyMailGUI
example in Chapter 14.


Later in this chapter, we’ll also meet the multiprocessing module, whose process and
queue support offers new options for implementing this GUI model using processes
instead of threads; as such, they work around the limitations of the thread GIL, but
may incur extra performance overheads that can vary per platform, and may not be
directly usable at all in threading contexts (the direct shared and mutable object state
of threads is not supported, though messaging is). For now, let’s cover a few final thread
fine points.


Thread Timers versus GUI Timers
Interestingly, the threading module exports a general timer function, which, like the
tkinter widget after method, can be used to run another function after a timer has
expired:
Timer(N.M, somefunc).start() # after N.M seconds run somefunc
Timer objects have a start() method to set the timer as well as a cancel() method to
cancel the scheduled event, and they implement the wait state in a spawned thread.
For example, the following prints a message after 5.5 seconds:
>>> import sys
>>> from threading import Timer
>>> t = Timer(5.5, lambda: print('Spam!')) # spawned thread
>>> t.start()
>>> Spam!
This may be useful in a variety of contexts, but it doesn’t quite apply to GUIs: because
the time-delayed function call is run in a spawned thread, not in the main GUI thread,
it should not generally perform GUI updates. Because the tkinter after method is run
from the main thread’s event processing loop instead, it runs in the main GUI thread
and can freely update the GUI.
As a preview, for instance, the following displays a pop-up message window in 5.5
seconds in the main thread of a tkinter GUI (you might also have to run win.main
loop() in some interfaces):
>>> from tkinter import Tk
>>> from tkinter.messagebox import showinfo
>>> win = Tk()
>>> win.after(5500, lambda: showinfo('Popup', 'Spam!'))
The last call here schedules the function to be run once in the main GUI thread, but it
does not pause the caller during the wait, and so does not block the GUI. It’s equivalent
to this simpler form:
>>> win.after(5500, showinfo, 'Popup', 'Spam')
Stay tuned for much more on tkinter in the next part of this book, and watch for the
full story on its after timer events in Chapter 9 and the roles of threads in GUIs in
Chapter 10.

210 | Chapter 5: Parallel System Tools

Free download pdf