wierdness with pythonwin dialogs, threads & refcounts

Gordon McMillan gmcm at hypernet.com
Thu Jun 17 10:21:51 EDT 1999


Dave Kirby writes:
 
> I have found strange behaviour (strange to me at least) when
> creating a pythonwin dialog on a separate thread created using the
> standard python thread module.  The dialog object is never deleted
> since the thread is keeping references to it. 
> 
> The following example uses dlgtest.py that comes with the pythonwin
> distribution:
> 
> #------------- 8< ----------------------------
> C:\dev\PYTHON\Pythonwin\pywin\DEMOS>python
> Python 1.5.2 (#0, Apr 13 1999, 10:51:12) [MSC 32 bit (Intel)] on
> win32 Copyright 1991-1995 Stichting Mathematisch Centrum, Amsterdam
> >>> from dlgtest import TestDialog
> >>> import sys, thread
> >>> def test():
> ...   t = TestDialog()
> ...   print "refs:", sys.getrefcount(t)
> ...   t = None
> ...
> >>> test()
> Edit text changed!
> refs: 2
> >>> thread.start_new_thread( test, () )
> >>> refs: 6
> #------------- 8< ----------------------------
> 
> As you can see from the above, creating the dialog in the thread
> gives it an extra 4 references compared with the non-threaded
> invocation. Is this a bug, or is the thread module incompatible with
> pythonwin? If so how would I do the equivalent using pythonwin
> threads?  I have read the available docs, but it is still pretty
> opaque to me.

First, there's no incompatibility with the thread module in 
Pythonwin. 

Second, you should use threading.py, not the low level thread module 
(which is very, very primitive). Or you can use 
win32process.beginthreadex which is a wrapper around MFC threads. 
This lets you manipulate priorities. (As of a couple years ago, there 
was a small memory leak involved with using MFC threads, however).

As for the source of your questions - without doing things in a debug 
build of python / Pythonwin, it's almost impossible to tell what's 
going on, or even if there really is a problem.

Using sys.getrefcount increments the refcount. Printing something in 
the interactive interp binds the thing to a var named "_" (to 
optimize looking at it again). Printing to stdout in Pythonwin 
involves all kinds of hidden manipulations.

If you want to know whether you're leaking TestDialogs you could code 
a loop that creates threading.Thread's that show a TestDialog and 
then joins the Thread. Run it for as many iterations as you can 
stand, and watch the process in TaskManager.

hope-you're-not-prone-to-Carpal-Tunnel-Syndrome-ly y'rs



- Gordon




More information about the Python-list mailing list