Exit Application - process still active

Hello,

I stumbled on a strange behavior where i can't understand what is
still running after i exited the application.

def DoExit(frame):
     frame.Destroy()
     wx.GetApp().Exit() # or wx.GetApp().ExitMainLoop()

I tried both wx.GetApp().Exit() and wx.GetApp().ExitMainLoop().

When i am using pydev to debug step after step (both ExitMainLoop()
and Exit() ) i successfully exit the app, although if running the app
not in debug mode , something still runs after the frame is destroyed.

what can it be, and how i can find it?

is their a method which exits everything even if something runs in the
background?

Maybe some top level Window not closed, e.g. Dialog or ...

I often use this in my OnExit:

         # make sure that all is closed
         for item in wx.GetTopLevelWindows():
             if not isinstance(item, CaptureFrame):
                 if isinstance(item, wx.Dialog):
                     item.Destroy()
                 item.Close()

"CaptureFrame" is in this case my MainFrame, don't close that otherwise IIRC you get a py dead error.

Werner

···

On 01/09/2012 10:31 AM, Michael Gorelik wrote:

Hello,

I stumbled on a strange behavior where i can't understand what is
still running after i exited the application.

def DoExit(frame):
      frame.Destroy()
      wx.GetApp().Exit() # or wx.GetApp().ExitMainLoop()

I tried both wx.GetApp().Exit() and wx.GetApp().ExitMainLoop().

When i am using pydev to debug step after step (both ExitMainLoop()
and Exit() ) i successfully exit the app, although if running the app
not in debug mode , something still runs after the frame is destroyed.

what can it be, and how i can find it?

is their a method which exits everything even if something runs in the
background?

This didn't solve my problem,

i have printed all items while looping through the
wx.GetTopLevelWindows():

   MyMainFrame: <__main__.MyMainFrame; proxy of <Swig Object of type
'wxFrame *' at 0x3958a28> >
   Frame: <wx._windows.Frame; proxy of <Swig Object of type 'wxFrame
*' at 0x3959270> >

and i replaced "CaptureFrame" by "MyMainFrame"

When i finished iterating over the loop (closed only the Frame:
<wx._windows.Frame; proxy of <Swig Object of type 'wxFrame *' at
0x3959270> >)
I execute the close method of the instance of type MyMainFrame
(frame.Close())

       def DoExit(frame):
# make sure that all is closed
for item in wx.GetTopLevelWindows():
if not isinstance(item, MyMainFrame):
if isinstance(item, wx.Dialog):
item.Destroy()
item.Close()
          frame.Close()
          wx.GetApp().ExitMainLoop()

The result is the same behavior i had before, where is my mistake?

···

On Jan 9, 12:29 pm, werner <wbru...@free.fr> wrote:

On 01/09/2012 10:31 AM, Michael Gorelik wrote:

> Hello,

> I stumbled on a strange behavior where i can't understand what is
> still running after i exited the application.

> def DoExit(frame):
> frame.Destroy()
> wx.GetApp().Exit() # or wx.GetApp().ExitMainLoop()

> I tried both wx.GetApp().Exit() and wx.GetApp().ExitMainLoop().

> When i am using pydev to debug step after step (both ExitMainLoop()
> and Exit() ) i successfully exit the app, although if running the app
> not in debug mode , something still runs after the frame is destroyed.

> what can it be, and how i can find it?

> is their a method which exits everything even if something runs in the
> background?

Maybe some top level Window not closed, e.g. Dialog or ...

I often use this in my OnExit:

     \# make sure that all is closed
     for item in wx\.GetTopLevelWindows\(\):
         if not isinstance\(item, CaptureFrame\):
             if isinstance\(item, wx\.Dialog\):
                 item\.Destroy\(\)
             item\.Close\(\)

"CaptureFrame" is in this case my MainFrame, don't close that otherwise
IIRC you get a py dead error.

Werner

Don't know if it will help but I have often seen this sort of problem in
my code when I have a dialogue that is not destroyed before exit,
sometimes because of an exception.

Gadget/Steve

···

On 09/01/2012 10:59 AM, Michael Gorelik wrote:

This didn't solve my problem,

i have printed all items while looping through the
wx.GetTopLevelWindows():

   MyMainFrame: <__main__.MyMainFrame; proxy of <Swig Object of type
'wxFrame *' at 0x3958a28> >
   Frame: <wx._windows.Frame; proxy of <Swig Object of type 'wxFrame
*' at 0x3959270> >

and i replaced "CaptureFrame" by "MyMainFrame"

When i finished iterating over the loop (closed only the Frame:
<wx._windows.Frame; proxy of <Swig Object of type 'wxFrame *' at
0x3959270> >)
I execute the close method of the instance of type MyMainFrame
(frame.Close())

       def DoExit(frame):
          # make sure that all is closed
          for item in wx.GetTopLevelWindows():
              if not isinstance(item, MyMainFrame):
                  if isinstance(item, wx.Dialog):
                      item.Destroy()
                  item.Close()
          frame.Close()
          wx.GetApp().ExitMainLoop()

The result is the same behavior i had before, where is my mistake?

On Jan 9, 12:29 pm, werner <wbru...@free.fr> wrote:

On 01/09/2012 10:31 AM, Michael Gorelik wrote:

Hello,
I stumbled on a strange behavior where i can't understand what is
still running after i exited the application.
def DoExit(frame):
      frame.Destroy()
      wx.GetApp().Exit() # or wx.GetApp().ExitMainLoop()
I tried both wx.GetApp().Exit() and wx.GetApp().ExitMainLoop().
When i am using pydev to debug step after step (both ExitMainLoop()
and Exit() ) i successfully exit the app, although if running the app
not in debug mode , something still runs after the frame is destroyed.
what can it be, and how i can find it?
is their a method which exits everything even if something runs in the
background?

Maybe some top level Window not closed, e.g. Dialog or ...

I often use this in my OnExit:

         # make sure that all is closed
         for item in wx.GetTopLevelWindows():
             if not isinstance(item, CaptureFrame):
                 if isinstance(item, wx.Dialog):
                     item.Destroy()
                 item.Close()

"CaptureFrame" is in this case my MainFrame, don't close that otherwise
IIRC you get a py dead error.

Werner

Any timers in your app which are still running? BTW, did you want to use DoExit instead of override OnExit? I use the later then you don't need your last two lines.

Maybe time for a small runnable sample.

Werner

···

On 01/09/2012 11:59 AM, Michael Gorelik wrote:

This didn't solve my problem,

i have printed all items while looping through the
wx.GetTopLevelWindows():

    MyMainFrame:<__main__.MyMainFrame; proxy of<Swig Object of type
'wxFrame *' at 0x3958a28> >
    Frame:<wx._windows.Frame; proxy of<Swig Object of type 'wxFrame
*' at 0x3959270> >

and i replaced "CaptureFrame" by "MyMainFrame"

When i finished iterating over the loop (closed only the Frame:
<wx._windows.Frame; proxy of<Swig Object of type 'wxFrame *' at
0x3959270> >)
I execute the close method of the instance of type MyMainFrame
(frame.Close())

        def DoExit(frame):
           # make sure that all is closed
           for item in wx.GetTopLevelWindows():
               if not isinstance(item, MyMainFrame):
                   if isinstance(item, wx.Dialog):
                       item.Destroy()
                   item.Close()
           frame.Close()
           wx.GetApp().ExitMainLoop()

The result is the same behavior i had before, where is my mistake?

1. I use DoExit() since i invoke it from different places of a code
(inner panel, platebtn etc..)
2. I do have a timer that is used for a music player and acts the same
like in this example : http://www.blog.pythonlibrary.org/2010/04/20/wxpython-creating-a-simple-mp3-player/
3. Currently i tried to add the line frame.timer.Stop() in the
DoExit() function, (in the init of the panel that is responsible for
the media player i wrote self.parent.timer = self.timer so that the
frame will be familiar with the timer), than i tried to exit the
application again using DoExit() and i got the same behavior like was
described before.

···

On Jan 9, 1:44 pm, werner <wbru...@free.fr> wrote:

On 01/09/2012 11:59 AM, Michael Gorelik wrote:

> This didn't solve my problem,

> i have printed all items while looping through the
> wx.GetTopLevelWindows():

> MyMainFrame:<__main__.MyMainFrame; proxy of<Swig Object of type
> 'wxFrame *' at 0x3958a28> >
> Frame:<wx._windows.Frame; proxy of<Swig Object of type 'wxFrame
> *' at 0x3959270> >

> and i replaced "CaptureFrame" by "MyMainFrame"

> When i finished iterating over the loop (closed only the Frame:
> <wx._windows.Frame; proxy of<Swig Object of type 'wxFrame *' at
> 0x3959270> >)
> I execute the close method of the instance of type MyMainFrame
> (frame.Close())

> def DoExit(frame):
> # make sure that all is closed
> for item in wx.GetTopLevelWindows():
> if not isinstance(item, MyMainFrame):
> if isinstance(item, wx.Dialog):
> item.Destroy()
> item.Close()
> frame.Close()
> wx.GetApp().ExitMainLoop()

> The result is the same behavior i had before, where is my mistake?

Any timers in your app which are still running? BTW, did you want to
use DoExit instead of override OnExit? I use the later then you don't
need your last two lines.

Maybe time for a small runnable sample.

Werner

Ok, I don't know why this is happens, but i succeed to trick the
system , and now it works:

from multiprocessing import Process

def test(name):
    MyApp(0).MainLoop()

if __name__ == '__main__':
    p = Process(target=test, args=('',))
    p.start()
    p.join()

My idea was that any other window or dialog or any widget that is
created, can be only created in the same or additional thread.
If i join the main thread, i enforce killing all the children threads
that finished working but still active.

My solution is not perfect since there is a good reason why i still
have leftovers somewhere in the app, but it certainly kills everything
that is related to my app.
Feel free to use it :slight_smile:

···

On Jan 9, 2:33 pm, Michael Gorelik <smgore...@gmail.com> wrote:

1. I use DoExit() since i invoke it from different places of a code
(inner panel, platebtn etc..)
2. I do have a timer that is used for a music player and acts the same
like in this example :http://www.blog.pythonlibrary.org/2010/04/20/wxpython-creating-a-simp
3. Currently i tried to add the line frame.timer.Stop() in the
DoExit() function, (in the init of the panel that is responsible for
the media player i wrote self.parent.timer = self.timer so that the
frame will be familiar with the timer), than i tried to exit the
application again using DoExit() and i got the same behavior like was
described before.

On Jan 9, 1:44 pm, werner <wbru...@free.fr> wrote:

> On 01/09/2012 11:59 AM, Michael Gorelik wrote:

> > This didn't solve my problem,

> > i have printed all items while looping through the
> > wx.GetTopLevelWindows():

> > MyMainFrame:<__main__.MyMainFrame; proxy of<Swig Object of type
> > 'wxFrame *' at 0x3958a28> >
> > Frame:<wx._windows.Frame; proxy of<Swig Object of type 'wxFrame
> > *' at 0x3959270> >

> > and i replaced "CaptureFrame" by "MyMainFrame"

> > When i finished iterating over the loop (closed only the Frame:
> > <wx._windows.Frame; proxy of<Swig Object of type 'wxFrame *' at
> > 0x3959270> >)
> > I execute the close method of the instance of type MyMainFrame
> > (frame.Close())

> > def DoExit(frame):
> > # make sure that all is closed
> > for item in wx.GetTopLevelWindows():
> > if not isinstance(item, MyMainFrame):
> > if isinstance(item, wx.Dialog):
> > item.Destroy()
> > item.Close()
> > frame.Close()
> > wx.GetApp().ExitMainLoop()

> > The result is the same behavior i had before, where is my mistake?

> Any timers in your app which are still running? BTW, did you want to
> use DoExit instead of override OnExit? I use the later then you don't
> need your last two lines.

> Maybe time for a small runnable sample.

> Werner

Creating a new process just so you can have a clean exit seems like trying to kill a mosquito with a grenade, IOW way too much overkill. The things to double-check are:

1. As others have mentioned, if you have any other TLWs remaining then the MainLoop will not exit normally, but even so ExitMainLoop should have taken care of that for you as long as you're not currently in a nested event loop.

2. Are you using a TaskBarIcon? If so then it should be Destroyed.

3. Are you using other threads (or multiprocessing processes) that have not terminated or been set to be daemon threads? If your MainLoop() is exiting but Python is not exiting then this is probably the problem. Python itself will not exit while there are non-daemon threads still running.

If all else fails you should be able to use wx.Exit() to force it, but if you can figure it out it would be better to find out why the normal termination is not happening and fix it, just to make sure you are properly cleaning up any resources you are creating or modifying. Can you reproduce the problem in a small, simple standalone program? If so that will probably point you to the source of the issue.

···

On 1/9/12 6:10 AM, Michael Gorelik wrote:

Ok, I don't know why this is happens, but i succeed to trick the
system , and now it works:

from multiprocessing import Process

def test(name):
     MyApp(0).MainLoop()

if __name__ == '__main__':
     p = Process(target=test, args=('',))
     p.start()
     p.join()

My idea was that any other window or dialog or any widget that is
created, can be only created in the same or additional thread.
If i join the main thread, i enforce killing all the children threads
that finished working but still active.

My solution is not perfect since there is a good reason why i still
have leftovers somewhere in the app, but it certainly kills everything
that is related to my app.
Feel free to use it :slight_smile:

--
Robin Dunn
Software Craftsman

wx.Exit() is one that i missed and it works using this function ,

i tried on a smaller program without task-bar icon (a removed it in
all previous examples) or mediaplayer but with a panel that contains
platebuttons (this is created instead of a regular menu)
and ExitMainLoop produced the same behavior.

and not i am not using multi-threading "in my code".

I will try to produce a small example tomorrow and to attach it here,

btw: i can't find how to attach here a document.

···

On Jan 9, 7:34 pm, Robin Dunn <ro...@alldunn.com> wrote:

On 1/9/12 6:10 AM, Michael Gorelik wrote:

> Ok, I don't know why this is happens, but i succeed to trick the
> system , and now it works:

> from multiprocessing import Process

> def test(name):
> MyApp(0).MainLoop()

> if __name__ == '__main__':
> p = Process(target=test, args=('',))
> p.start()
> p.join()

> My idea was that any other window or dialog or any widget that is
> created, can be only created in the same or additional thread.
> If i join the main thread, i enforce killing all the children threads
> that finished working but still active.

> My solution is not perfect since there is a good reason why i still
> have leftovers somewhere in the app, but it certainly kills everything
> that is related to my app.
> Feel free to use it :slight_smile:

Creating a new process just so you can have a clean exit seems like
trying to kill a mosquito with a grenade, IOW way too much overkill.
The things to double-check are:

1. As others have mentioned, if you have any other TLWs remaining then
the MainLoop will not exit normally, but even so ExitMainLoop should
have taken care of that for you as long as you're not currently in a
nested event loop.

2. Are you using a TaskBarIcon? If so then it should be Destroyed.

3. Are you using other threads (or multiprocessing processes) that have
not terminated or been set to be daemon threads? If your MainLoop() is
exiting but Python is not exiting then this is probably the problem.
Python itself will not exit while there are non-daemon threads still
running.

If all else fails you should be able to use wx.Exit() to force it, but
if you can figure it out it would be better to find out why the normal
termination is not happening and fix it, just to make sure you are
properly cleaning up any resources you are creating or modifying. Can
you reproduce the problem in a small, simple standalone program? If so
that will probably point you to the source of the issue.

--
Robin Dunn
Software Craftsmanhttp://wxPython.org

As a Java developer who enjoys Python, I have to ask if there are any
tools for Python like jps and jstack? When I have a thread that isn't
terminating in Java, I can use these tools to get more insight into what
the VM is still running and track it down that way.

Greg

···

On 01/09/2012 12:34 PM, Robin Dunn wrote:

3. Are you using other threads (or multiprocessing processes) that have
not terminated or been set to be daemon threads? If your MainLoop() is
exiting but Python is not exiting then this is probably the problem.
Python itself will not exit while there are non-daemon threads still
running.

If all else fails you should be able to use wx.Exit() to force it, but
if you can figure it out it would be better to find out why the normal
termination is not happening and fix it, just to make sure you are
properly cleaning up any resources you are creating or modifying. Can
you reproduce the problem in a small, simple standalone program? If so
that will probably point you to the source of the issue.

I’m guessing it has something to do with Sun / Oracle paying their programmers to come up with some good tools vs. no one paying Python programmers for those same tools.

···

On Tue, Jan 10, 2012 at 7:50 AM, Greg Hasseler ghasseler@gmail.com wrote:

On 01/09/2012 12:34 PM, Robin Dunn wrote:

  1. Are you using other threads (or multiprocessing processes) that have

not terminated or been set to be daemon threads? If your MainLoop() is

exiting but Python is not exiting then this is probably the problem.

Python itself will not exit while there are non-daemon threads still

running.

If all else fails you should be able to use wx.Exit() to force it, but

if you can figure it out it would be better to find out why the normal

termination is not happening and fix it, just to make sure you are

properly cleaning up any resources you are creating or modifying. Can

you reproduce the problem in a small, simple standalone program? If so

that will probably point you to the source of the issue.

As a Java developer who enjoys Python, I have to ask if there are any

tools for Python like jps and jstack? When I have a thread that isn’t

terminating in Java, I can use these tools to get more insight into what

the VM is still running and track it down that way.

Greg


Mike Driscoll

Blog: http://blog.pythonlibrary.org

Hi,

3. Are you using other threads (or multiprocessing processes) that have
not terminated or been set to be daemon threads? If your MainLoop() is
exiting but Python is not exiting then this is probably the problem.
Python itself will not exit while there are non-daemon threads still
running.

If all else fails you should be able to use wx.Exit() to force it, but
if you can figure it out it would be better to find out why the normal
termination is not happening and fix it, just to make sure you are
properly cleaning up any resources you are creating or modifying. Can
you reproduce the problem in a small, simple standalone program? If so
that will probably point you to the source of the issue.

As a Java developer who enjoys Python, I have to ask if there are any
tools for Python like jps and jstack? When I have a thread that isn't
terminating in Java, I can use these tools to get more insight into what
the VM is still running and track it down that way.

You can use a debugger such as WinPdb to view the threads and
callstack. Only issue is if the code is stuck outside of the Python
code (i.e down a the C/C++ library a python debugger may not be of
much use.)

Also see the PyStudio plugin for Editra which has WinPdb integration
(Google Code Archive - Long-term storage for Google Code Project Hosting.)

Cody

···

On Tue, Jan 10, 2012 at 7:50 AM, Greg Hasseler <ghasseler@gmail.com> wrote:

On 01/09/2012 12:34 PM, Robin Dunn wrote:

There is the wx inspect tool - this will often let you see hanging
elements, WinPdb will also provide a lot of help and there was an
announcement on the Python mailing list of pystuck - take a look at:

As I haven't personally used the latter I can not say how useful it might be but it sounds like exactly what you need.

Gadget/Steve

···

On 10/01/2012 1:50 PM, Greg Hasseler wrote:

On 01/09/2012 12:34 PM, Robin Dunn wrote:

3. Are you using other threads (or multiprocessing processes) that have
not terminated or been set to be daemon threads? If your MainLoop() is
exiting but Python is not exiting then this is probably the problem.
Python itself will not exit while there are non-daemon threads still
running.

If all else fails you should be able to use wx.Exit() to force it, but
if you can figure it out it would be better to find out why the normal
termination is not happening and fix it, just to make sure you are
properly cleaning up any resources you are creating or modifying. Can
you reproduce the problem in a small, simple standalone program? If so
that will probably point you to the source of the issue.

As a Java developer who enjoys Python, I have to ask if there are any
tools for Python like jps and jstack? When I have a thread that isn't
terminating in Java, I can use these tools to get more insight into what
the VM is still running and track it down that way.

Greg