Hmm,  I see what your getting at, I'll read up on the subject and then try
out the theory below.  Threading is something I've never had to deal with
before, I have a lot to read up on today... :)

-Dave

On Fri, Sep 25, 2009 at 12:50 AM, Chris G <[email protected]> wrote:

>
> Thats an imaginative workaround! =)
>
> I think the issue is that eventually there is a huge backlog of idle
> events that starts slowing everything down.
> If we can ensure that we never add another idle event until the
> previous one is processed we should be good.  So maybe try using an
> Event:
>
> def pumpQt():
>       global app
>       global gPump
>        processorEv = threading.Event()
>       def processor():
>               app.processEvents()
>               processorEv.set()
>       while gPump:
>               utils.executeDeferred(processor)
>               # block until processor has run
>               processorEv.wait()
>               # aha, processor has completed, so now we sleep and repeat
>               processorEv.clear()
>               time.sleep(0.01)
>               print "pump..."
>
> -Chris
>
>
> On Thu, Sep 24, 2009 at 5:29 PM, David Moulder <[email protected]>
> wrote:
> > pumpThread is running in the background when any PyQt window is opened
> > because that UI has called initializePumpThread().
> > So the users are :-
> >
> > Opening a PyQt window.
> > Then close that PyQt Gui.
> > Then close Maya as normal.
> >
> > 7/10 times 1 thread will be left open.
> > So I've setup a script job that calls killPumpThread on maya exit.  This
> has
> > reduced the number of time's 1 thread is still left open.  This happens
> on
> > both 2009, 2010, 2009x64 and 2010x64, XP and Vista.  The UI is nothing
> but a
> > empty QDialog for testing. But infact, if you remove a PyQt UI from the
> > problem and just put a print in the pumpQt() call.  Open maya and manualy
> > start a thread by initializePumpThread() and repeat the above steps
> (without
> > my script job calling killPumpThread ) then maya might close, and might
> > not.  And by that I mean you might have to press the close button 10x
> before
> > the Maya will close.
> >
> > # The print call to test pumpThread
> > def pumpQt():
> >         global app
> >         global gPump
> >         def processor():
> >                 app.processEvents()
> >                 print "Pump"
> >         while gPump:
> >                 time.sleep(0.01)
> >                 utils.executeDeferred( processor )
> >
> > I've solved the problem today in a hacky but reliable way.  In the
> > initializePumpThread() I'm using DotNet via clr to determin if a maya
> > process is running with one thread.  If so I kill it, cleaning up any
> rouge
> > bad pumpThreads.  Also in the scriptJob I'm using DotNet to get the
> current
> > process and kill it.  The whole thing is evalDeffered but with some heavy
> > testing, it's saving all the prefs for maya correctly, before it kill's
> Maya
> > for good.
> >
> > When I'm at work if anyone's interested I'll post the new pumpThread
> hacks
> > here.  I'm wondering if not alot of people have come across this problem?
> > It's very consistant problem here.  Either people have'nt noticed it, are
> > not using PyQt in production.  If you are using PyQt and could post that
> you
> > are :) then I'd like to hear from you.
> >
> > -Dave
> >
> >
> > On Thu, Sep 24, 2009 at 8:01 PM, Chris G <[email protected]> wrote:
> >>
> >> When you say "when users closes Maya" does that mean the user is going
> >> through something that calls killPumpThread ?  Or are they bypassing
> >> that?  Do you see problems in both cases?
> >>
> >>
> >>
> >> On Thu, Sep 24, 2009 at 4:41 AM, [email protected]
> >> <[email protected]> wrote:
> >> >
> >> > Hi guys,
> >> >
> >> > Tried get_pt().setDaemon(True)...
> >> > This seemed to make no difference what so ever.  Maya is still
> >> > randomly leaving 1 thread open.
> >> >
> >> > So with no other option.  I've added a scriptJob to pumpThread.  This
> >> > has helped reduce the amount of times the thread is left open.
> >> > Happens about half the time now.  But it's still a problem.  So, what
> >> > else can I do?  It's seems that I'll have to write a service to check
> >> > for a Maya application with just 1 thread.  Then manually kill the
> >> > thread.
> >> >
> >> > Alternatively I could do this as a python script when maya starts/or
> >> > closes.  Anybody know of a way to "kill a process tree" from default
> >> > python?
> >> >
> >> > -Dave
> >> >
> >> >
> >> > On Sep 16, 10:37 pm, David Moulder <[email protected]> wrote:
> >> >> Hmm.  1st I've heard of daemonic.  I'll give it a go tomorrow.
> >> >>
> >> >> Cheers
> >> >>
> >> >> -Dave
> >> >>
> >> >> On Wed, Sep 16, 2009 at 2:52 PM, Chris G <[email protected]> wrote:
> >> >>
> >> >> > Have you tried setting Thread.deamon / Thread.setDaemon() ?
> >> >> > If the thread is not daemonic, it may block python finalization.
> >> >>
> >> >> > -Chris
> >> >>
> >> >> > On Wed, Sep 16, 2009 at 6:25 AM, thirstydevil
> >> >> > <[email protected]>
> >> >> > wrote:
> >> >>
> >> >> > > I've noticed a few issues using PyQt and pumpThread.  It seems
> that
> >> >> > > randomly when users closes Maya it will do 1 of these:
> >> >>
> >> >> > > 1) Close successfully.
> >> >> > > 2) Not closes. Instead require 2 close requests by the user.
> >> >> > > 3) Closes but leaves 1 Maya thread running ( the pumpThread ) and
> >> >> > > still consuming Maya's memory footprint
> >> >>
> >> >> > > In an attempt to understand the problem I've reconfigured
> >> >> > > pumpThread
> >> >> > > based on Jon's and another user's version posted here (can't
> >> >> > > remember
> >> >> > > who and cant be bothered to hunt for it again, sorry to who ever
> >> >> > > you
> >> >> > > are).  I'll blat out my thoughts and you guys can hopefully
> correct
> >> >> > > me
> >> >> > > or confirm my understanding.
> >> >>
> >> >> >
> >> >> >
> -----------------------------------------------------------------------------------------------------------------------------------------------------------------
> >> >>
> >> >> > > I've not done any multi threading stuff before, but this is what
> I
> >> >> > > understand is happening with pumpThread and the way in which it's
> >> >> > > operating.
> >> >>
> >> >> > > pumpThread is spawning 1 sub thread from Maya's main thread.  The
> >> >> > > UI
> >> >> > > is executing in that new thread.
> >> >> > > threading.Thread( target = pumpQt, args = () )
> >> >>
> >> >> > > Whenever a maya cmd is called in the PyQt UI code it is called
> with
> >> >> > > utils.executeDeferred( processor ) in pumpQt block.
> >> >>
> >> >> > > This intern is executed in maya's main thread when it can.  I
> >> >> > > simply
> >> >> > > added the following line to the pumpQt whille loop print
> "pump..."
> >> >> > > makes sure a maya cmd is called every pumpThread cycle.
> >> >>
> >> >> > > As this loop is executing quicker than maya's main loop and stack
> >> >> > > of
> >> >> > > evalDeffered print statements build up in the main thread.  In my
> >> >> > > pumpThread module I've created a global for the while loop
> (gPump).
> >> >> > > Using killPumpThread I can instantly stop and close the thread.
> >> >> > >  But
> >> >> > > Maya is still printing "pump..." untill the stack of evalDeffered
> >> >> > > cmds
> >> >> > > have finished.
> >> >>
> >> >> > > Here's my test code with my new pumpThread module
> >> >>
> >> >> > > import pumpThread
> >> >> > > pumpThread.initializePumpThread()
> >> >> > > # Wait 20 secs
> >> >> > > pumpThread.killPumpThread()
> >> >> > > # only a small number of prints executed after thread is closed.
> >> >> > > Maybe
> >> >> > > 2-5 cycle depending
> >> >>
> >> >> > > # Load my PyQt UI and leave open and pumping for 20secs
> >> >> > > pumpThread.killPumpThread()
> >> >> > > # window closes quickly and tread die's in Task Manager.  But 926
> >> >> > > lines of pump... printed  before maya is finished
> >> >>
> >> >> > > So how does that relate to the 3 errors above?
> >> >>
> >> >> > > 1) Close successfully.
> >> >> > > Thread has closed in time and Maya has no evaldeffers in the
> stack
> >> >>
> >> >> > > 2) Not closes. Instead require 2 close requests by the user.
> >> >> > > Thread has closed in time but maya is still pumping
> >> >>
> >> >> > > 3) Closes but leaves 1 Maya thread running ( the pumpThread ) and
> >> >> > > still consuming Maya's memory footprint
> >> >> > > Thread didn't close, UI could have been left open or maya not
> >> >> > > closing
> >> >> > > sun threads properly?
> >> >>
> >> >> > > It seems I can't do anything about error 2  as this is down to
> how
> >> >> > > much and often the threads are communicating.  But I can help on
> >> >> > > error
> >> >> > > 3 by calling pumpThread.killPumpThread() with a script job on
> Maya
> >> >> > > exit.
> >> >>
> >> >> > > "RANT ON"
> >> >> > > I've spent nearly 6 months researching PyQt in Maya and so far
> >> >> > > (especially if you are having to support 64bit) I have to say
> it's
> >> >> > > allot of pain to maintain.  Maya doesn't play nicely and will
> crash
> >> >> > > with no warning if you try to do something wrong or something
> it's
> >> >> > > not
> >> >> > > happy with.  When you have 12 UI modules and 500 - 3000 lines of
> >> >> > > code
> >> >> > > in each it is a real headache to comment out blocks of code to
> find
> >> >> > > the line that is crashing Maya.  Sometimes it's not you.  I had
> one
> >> >> > > example where by I was creating a QIcon as a module global, it
> was
> >> >> > > being used allot in the UI.  This line had been in for months,
> but
> >> >> > > all
> >> >> > > of a sudden was crashing Maya.  I had to put the QIcon inside a
> >> >> > > class
> >> >> > > to solve the Maya crash.  Developing a complex UI as I have with
> >> >> > > PyQT
> >> >> > > with lots of dependencies on Maya tools, like Pymel and clr means
> >> >> > > that
> >> >> > > you loose the ability to run the UI in Wings with debugging.
> >> >> > > Something you really need.  Instead. I think using C++ Qt would
> >> >> > > give
> >> >> > > you the hooks to run in debug mode with Maya.  You wouldn't have
> to
> >> >> > > compile 64bit PyQt as well.  But then you loose the benefits of
> >> >> > > developing in a scripting environment.
> >> >> > > "RANT OFF"
> >> >>
> >> >> > > I'm sure that other studios trying to implement PyQT into there
> >> >> > > pipeline have faced these issues.  I was wondering if anyone else
> >> >> > > could shed some light of the pit falls and hoops you are jumping
> >> >> > > through.
> >> >>
> >> >> > > Anyway here is my edited pumpThread module
> >> >>
> >> >> > > -Dave
> >> >>
> >> >> >
> >> >> >
> ----------------------------------------------------------------------------------------------------------------------------------------------------------
> >> >>
> >> >> > > from PyQt4 import QtCore, QtGui
> >> >> > > import maya.utils as utils
> >> >> > > import sys
> >> >> > > import time
> >> >> > > import threading
> >> >> > > import gc
> >> >> > > import maya.cmds as cmds
> >> >>
> >> >> > > pumpedThread = None
> >> >> > > app = None
> >> >> > > gPump = True
> >> >>
> >> >> > > def get_app():
> >> >> > >        global app
> >> >> > >        return app
> >> >>
> >> >> > > def set_app(i_app):
> >> >> > >        global app
> >> >> > >        testAppInstance = QtCore.QCoreApplication.instance()
> >> >> > >        if testAppInstance:
> >> >> > >                app = testAppInstance
> >> >> > >        else:
> >> >> > >                app = i_app
> >> >>
> >> >> > > def get_pt():
> >> >> > >        global pumpedThread
> >> >> > >        return pumpedThread
> >> >>
> >> >> > > def set_pt(i_pt):
> >> >> > >        global pumpedThread
> >> >> > >        pumpedThread = i_pt
> >> >>
> >> >> > > def pumpQt():
> >> >> > >        global app
> >> >> > >        global gPump
> >> >> > >        def processor():
> >> >> > >                app.processEvents()
> >> >> > >        while gPump:
> >> >> > >                time.sleep(0.01)
> >> >> > >                utils.executeDeferred( processor )
> >> >> > >                #print "pump..."
> >> >>
> >> >> > > def killProcess():
> >> >> > >        global gPump
> >> >> > >        gPump = False
> >> >>
> >> >> > > def killPumpThread():
> >> >> > >        if get_app():
> >> >> > >                get_app().closeAllWindows()
> >> >> > >        if get_pt():
> >> >> > >                killProcess()
> >> >> > >                set_pt(None)
> >> >> > >                set_app(None)
> >> >> > >                gc.collect()
> >> >>
> >> >> > > class QThreader(QtCore.QThread):
> >> >> > >        '''An attempt to use QThread instead of Threading.  Counld
> >> >> > > get
> >> >> > > this to pump in the same fasion'''
> >> >> > >        def __init__(self, funcPointer, executeDeferred=True):
> >> >> > >                super(QThreader, self).__init__()
> >> >> > >                self.runThread = True
> >> >> > >                self.funcPointer = funcPointer
> >> >> > >                self.executeDeferred = executeDeferred
> >> >>
> >> >> > >        def run(self):
> >> >> > >                time = long(1)
> >> >> > >                while self.runThread:
> >> >> > >                        self.usleep(time)
> >> >> > >                        if self.executeDeferred:
> >> >> > >
> >> >> > >  utils.executeDeferred(self.funcPointer())
> >> >> > >                        else:
> >> >> > >                                self.funcPointer()
> >> >>
> >> >> > >        def killThread(self):
> >> >> > >                self.runThread=False
> >> >>
> >> >> > >        def startThread(self):
> >> >> > >                self.runThread=True
> >> >>
> >> >> > > def initializePumpThread():
> >> >> > >        global gPump
> >> >> > >        gPump = True
> >> >> > >        if get_pt() == None:
> >> >> > >                set_app(QtGui.QApplication(sys.argv))
> >> >> > >                set_pt(threading.Thread( target = pumpQt, args =
> ()
> >> >> > > ))
> >> >> > >                get_pt().start()
> >> >>
> >> >>
> >> > >
> >> >
> >>
> >>
> >
> >
> > >
> >
>
> >
>

--~--~---------~--~----~------------~-------~--~----~
http://groups.google.com/group/python_inside_maya
-~----------~----~----~----~------~----~------~--~---

Reply via email to