views:

921

answers:

4

I'm making a program for running simulations in Python, with a wxPython interface. In the program, you can create a simulation, and the program renders (=calculates) it for you. Rendering can be very time-consuming sometimes.

When the user starts a simulation, and defines an initial state, I want the program to render the simulation continuously in the background, while the user may be doing different things in the program. Sort of like a YouTube-style bar that fills up: You can play the simulation only up to the point that was rendered.

How should I run the rendering function?

+3  A: 

Launch a new process to render in background and periodically check to see if it has returned.

You can find the documentation for the subprocess module here and the multiprocess module here. As Jay said, multiprocess is probably better if you're using Python 2.6. That said, I don't think there would be any performance difference between the two. Multiprocess just seems to be a wrapper around subprocess making certain things easier to do.

While subprocess/multiprocess is the standard way to do this, you may also want to take a look at Parallel Python.

Chris Upchurch
I've never worked with multiple processes before. Where do I start? Also, I understood there are different ways of doing it. Which one should I choose?
cool-RR
N.B., keep in mind that since this is a program for doing simulations, performance is very important.
cool-RR
If you can use python 2.6, I believe the multiprocessing module would be the standard way of accomplishing this. It should give you just as much performance as your OS and hardware has to provide.
Jay Kominek
FYI if you're using Windows with wxPython, it's better to use 2.5 http://lists.wxwidgets.org/pipermail/wxpython-users/2009-March/085022.html
DrBloodmoney
I also heard about Stackless Python. Is it relevant? Is it better than subprocess/multiprocess?
cool-RR
+2  A: 

I would use a threading.Thread to run the code in the background and wx.CallAfter to post updates to my window thread to render them to the user.

thread = threading.Thread(target=self.do_work)
thread.setDaemon(True)
thread.start()

...

def do_work(self):
    # processing code here
    while processing:
        # do stuff
        wx.CallAfter(self.update_view, args, kwargs)

def update_view(self, args):
    # do stuff with args
    # since wx.CallAfter was used, it's safe to do GUI stuff here
FogleBird
A: 

If you don't mind using a very slightly different approach, you can have a look at stackless python and create a tasklet for your rendering process. I find it very easy to use personally.

attwad
+1  A: 

There's a fair bit of info on the wxPython wiki about long running tasks that might be useful. They basically make use a thread and wx.PostEvent to handle communication between the thread and the main wx event loop.

John Montgomery