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

(yzsuai) #1

def producer(id):
for i in range(5):
time.sleep(0.1)
print('put')
dataQueue.put('[producer id=%d, count=%d]' % (id, i))


def consumer(root):
try:
print('get')
data = dataQueue.get(block=False)
except queue.Empty:
pass
else:
root.insert('end', 'consumer got => %s\n' % str(data))
root.see('end')
root.after(250, lambda: consumer(root)) # 4 times per sec


def makethreads():
for i in range(4):
_thread.start_new_thread(producer, (i,))


if name == 'main':


main GUI thread: spawn batch of worker threads on each mouse click


from tkinter.scrolledtext import ScrolledText
root = ScrolledText()
root.pack()
root.bind('', lambda event: makethreads())
consumer(root) # start queue check loop in main thread
root.mainloop() # pop-up window, enter tk event loop


Observe how we fetch one queued data item per timer event here. This is on purpose;
although we could loop through all the data items queued on each timer event, this
might block the GUI indefinitely in pathological cases where many items are queued
quickly (imagine a fast telemetry interface suddenly queueing hundreds or thousands
of results all at once). Processing one item at a time ensures that the GUI will return to
its event loop to update the display and process new user inputs without becoming
blocked. The downside of this approach is that it may take awhile to work through
very many items placed on the queue. Hybrid schemes, such as dispatching at most N
queued items per timer event callback, might be useful in some such scenarios; we’ll
see an example like this later in this section (Example 10-20).


When this script is run, the main GUI thread displays the data it grabs off the queue
in the ScrolledText window captured in Figure 10-11. A new batch of four producer
threads is started each time you left-click in the window, and threads issue “get” and
“put” messages to the standard output stream (which isn’t synchronized in this exam-
ple—printed messages might overlap occasionally on some platforms, including Win-
dows). The producer threads issue sleep calls to simulate long-running tasks such as
downloading mail, fetching a query result, or waiting for input to show up on a socket
(more on sockets later in this chapter). I left-clicked multiple times to encourage thread
overlap in Figure 10-11.


GUIs, Threads, and Queues | 637
Free download pdf