Passing multiple values to a Thread

74 views
Skip to first unread message

Daniel Fontaine

unread,
Sep 8, 2011, 5:20:27 PM9/8/11
to wxPython-users
Hi.
Like a lot of people, I seem to be stuck on threading.

I have an app which retrieves multiple forms of user input
(wxTextCtrl, wxChoice, etc.)
This data is then crunched by a function. Being a newbie GUI
programmer, I didn't realize this would block the application's GUI
when a time-consuming function was called.

I did some research, and found out I probably needed threading. After
working through some examples, I tried to apply threading to my
application.
Unfortunately, I wasn't able to figure out how to pass the variables
containing user input to the new, data-crunching thread. I don't know
if I'm looking at it the wrong way, or if I completely missed
something.

Could someone try to specify and specific terms when/where I pass
multiple variables (can also be another data-type) containing the user
input to the new thread?

Thanks,
Daniel

Mike Driscoll

unread,
Sep 8, 2011, 5:25:07 PM9/8/11
to wxpytho...@googlegroups.com
I think this is probably the best all-encompassing article on wxPython and threads: http://wiki.wxpython.org/LongRunningTasks and this is a simple one: http://www.blog.pythonlibrary.org/2010/05/22/wxpython-and-threads/

When I start a new thread, I have always passed the information needed to it when I create the thread. Then I start the thread. If you need to actually send it additional data, then you'll probably need to read the Python documentation on the Threading module. Once you've passed the info and the thread finishes crunching the data, it can then tell the GUI to update using wx.CallAfter or wx.PostEvent.

-------------------
Mike Driscoll

Blog:   http://blog.pythonlibrary.org

Chris Weisiger

unread,
Sep 8, 2011, 5:35:32 PM9/8/11
to wxpytho...@googlegroups.com
On Thu, Sep 8, 2011 at 2:20 PM, Daniel Fontaine
<danielfo...@gmail.com> wrote:
>
> I did some research, and found out I probably needed threading.  After
> working through some examples, I tried to apply threading to my
> application.
> Unfortunately, I wasn't able to figure out how to pass the variables
> containing user input to the new, data-crunching thread.  I don't know
> if I'm looking at it the wrong way, or if I completely missed
> something.

Here's a simple script that demonstrates creating a standard Python
thread, passing it arguments, blocking on it, and getting a return
value via a queue:

import Queue
import threading

def crunch(a, b, c, resultQueue):
resultQueue.put((a * b) + c)

resultQueue = Queue.Queue()
thread = threading.Thread(target = crunch, args = [3, 5, 7, resultQueue])
thread.start()
thread.join()
print resultQueue.get()

Since you don't want to have your main thread block while the
data-cruncher runs, instead of having the "thread.join()" call (which
will block on the thread completion) and the queue, you can do
something like this instead at the end of crunch():

wx.CallAfter(processResult, (a * b) + c)

where processResult is another function, accepting one argument in this case.

Hope that helps.

-Chris

Robin Dunn

unread,
Sep 9, 2011, 3:42:10 AM9/9/11
to wxpytho...@googlegroups.com


A common pattern for doing this is a command queue. Basically you have
a queue object that the gui thread will add command objects to. Those
commands can be anything that is able to carry the information that you
want to be able to pass to the worker thread. Typically they would be
instances of some Command class that is specific to your application's
needs but really anything will work. When you create the worker thread
you give it a reference to that queue and it starts a loop that reads
the next command object from the queue, performs the command (whatever
it may be) and then does something with the results. (You could even do
something like have one of the attributes in the command object be a
function that should be called when the command is completed.) Since
Python's queue.Queue class is thread safe and will block in get() by
default if there are no items waiting in the queue yet then it is
perfect for implementing this pattern. You can also have more than one
instance of the worker thread processing items in the queue if needed.

Remember that anything that interacts with the GUI needs to be done in
the GUI thread, so you'll need to ensure that the results of the
worker(s) is passed to the GUI thread first before they are displayed in
the GUI. wx.CallAfter has a convenient side-effect that it is
thread-safe and will always call the function you pass it in the UI
thread as soon as any current and pending events are processed.


--
Robin Dunn
Software Craftsman
http://wxPython.org

Reply all
Reply to author
Forward
0 new messages