Tkinter deadlock on graceful exit

Matteo Landi matteo at matteolandi.net
Thu May 31 09:02:12 EDT 2012


On Thu, May 31, 2012 at 3:42 AM, Terry Reedy <tjreedy at udel.edu> wrote:
> On 5/30/2012 6:19 PM, Matteo Landi wrote:
>>
>> On May/28, Matteo Landi wrote:
>>>
>>> Hi list,
>>> recently I started to work on an application [1] which makes use of the
>>> Tkinter
>>> module to handle interaction with the user.  Simply put, the app is a
>>> text
>>> widget displaying a file filtered by given criteria, with a handy feature
>>> that
>>> the window is raised each time a new line is added to the widget.
>>>
>>> The application mainly consists of three threads:  the first one, the
>>> file
>>> processor, reads the file, filters the lines of interest, and pushes them
>>> into
>>> a shared queue (henceforth `lines_queue`);  the second one, the
>>> gui_updater,
>>> pops elements from `lines_queue`, and schedule GUI updates using the
>>> `after_idle` method of the Tkinter module;  finally the last one, the
>>> worker
>>> spawner, receives commands by the gui (by means of a shared queue,
>>> `filters_queue`), and drives the application, terminating or spawning new
>>> threads.
>>>
>>> For example, let's see what happens when you start the application, fill
>>> the
>>> filter entry and press Enter button:
>>> 1 the associated even handler is scheduled (we should be inside the
>>> Tkinter
>>>   mainloop thread), and the filter is pushed into `filters_queue`;
>>> 2 the worker spawner receives the new filter, terminate a possibly
>>> running
>>>   working thread, and once done, create a new file processor;
>>> 3 the file processor actually processes the file and fills the
>>> `lines_queue`
>>>   with the lines matching given filter;
>>> 4 the gui updater schedules GUI updates as soon as items are pushed into
>>>   `lines_queue`
>>> 5 Tkinter mainloop thread updates the gui when idle
>>>
>>> What happens when the main window is closed?  Here is how I implemented
>>> the
>>> graceful shutdown of the app:
>>> 1 a quit event is scheduled and a _special_ message is pushed into both
>>>   `filter_queue` and `lines_queue`
>>> 2 the gui updater threads receives the _special_ message, and terminates
>>> 3 the worker spawner receives the message, terminates the working thread
>>> and
>>>   interrupts her execution.
>>> 4 Tk.quit() is called after the quit event handler, and we finally quit
>>> the
>>>   mainloop
>>>
>>> Honestly speaking, I see no issues with the algorithm presented above;
>>>  however,
>>> if I close the window in the middle of updates of the text widget, the
>>> applications hangs indefinitely.  On the other hand, everything works as
>>> expected if I close the app when the file processor, for example, is
>>> waiting for
>>> new content to filter.
>>>
>>> I put some logging messages to analyze the deadlock (?!), and noticed
>>> that both
>>> the worker spawner and the file processor are terminated correctly.  The
>>> only
>>> thread still active for some strange reasons, is the gui updater.
>>>
>>> Do you see anything wrong with the description presented above?  Please
>>> say so,
>>> because I can't figure it out!
>
>
> Since no-one else answered, I will ask some questions based on little
> tkinter experience, no thread experience, and a bit of python-list reading.
>
> 1. Are you only using tkinter in one thread? (It seems like so from the
> above)?

Yes, provided that `after_idle` queues a job for the gui thread

>
> 2. Is root.destroy getting called, as in 24.1.2.2. A Simple Hello World
> Program in the most recent docs? (I specify 'most recent' because that
> example has been recently revised because the previous version sometimes
> left tkinter hanging for one of the code paths, perhaps similar to what you
> describe.

No, I'm not calling the destroy method of the main window but, why
that only happens while doing gui updates?

>
> 3. Have you tried making the gui thread the master thread? (I somehow expect
> that the gui thread should be the last to shut down.)

No but, same question as above.

I'm not home right now, so I will try those solutions as soon as
possible.  Thanks.


Cheers,
Matteo

>
> --
> Terry Jan Reedy
>
> --
> http://mail.python.org/mailman/listinfo/python-list



-- 
http://www.matteolandi.net/



More information about the Python-list mailing list