Thread safety in wxpython

46 views
Skip to first unread message

Olivia Waring

unread,
Apr 23, 2015, 11:46:34 AM4/23/15
to wxpytho...@googlegroups.com

I'm using wxpython to build the front-end GUI for a command-line tool that analyzes and processes audio files. The files are loaded into the GUI; then threads are launched that perform the analysis and adjustment steps; and finally the results of those processes are displayed in the main window.

I have endeavored to write thread safe code; however, some threads still arbitrarily fail to complete (it should be noted that when I manually launch them a second time, they typically run to completion). I have attached an abridged version of my program, which defines classes for the AnalysisThread, the AdjustThread, and the MainWindow. Buttons in the main window are bound to the functions "OnAnalyze" and "OnAdjust," which create instances of the appropriate thread classes. The threads themselves communicate with the GUI via wx.CallAfter and Publisher. To my understanding, this should allow data to be passed safely back and forth between the main process and the threads. If someone could kindly point out where I went wrong with the attached code, I'd be very grateful.

If I cannot fix the thread safety issue, my back-up plan is to somehow detect the death of a thread and try to "resuscitate" it under the hood, without the user knowing there was a glitch. Does this seem reasonable? If so, advice on how to accomplish this would be most welcome.

Thanks very much. 

Abridgedwxpython.txt

Tim Roberts

unread,
Apr 23, 2015, 1:03:52 PM4/23/15
to wxpytho...@googlegroups.com
Olivia Waring wrote:
>
> I'm using wxpython to build the front-end GUI for a command-line tool
> that analyzes and processes audio files. The files are loaded into the
> GUI; then threads are launched that perform the analysis and
> adjustment steps; and finally the results of those processes are
> displayed in the main window.
>
> I have endeavored to write thread safe code; however, some threads
> still arbitrarily fail to complete...
>

What does that mean, exactly? Does the ffmpeg process simply never
terminate? Or does the process terminate, but you don't detect it?

Since you don't need to do anything while the command is running, you
might consider using subprocess.getoutput or subprocess.getstatusoutput
instead of the polling loops you currently have. Also, I can't help but
point out that this:

if line:
endProcess = re.search(r'Summary', line)
if endProcess is not None:
flag = 1
if flag:
summary += line

is equivalent to this:

if line and 'Summary' in line:
summary += line

By the way, this is not the traditional definition of "thread-safe
code". That term usually refers to problems with interlocking and data
sharing, which is not applicable here.


> If I cannot fix the thread safety issue, my back-up plan is to somehow
> detect the death of a thread and try to "resuscitate" it under the
> hood, without the user knowing there was a glitch. Does this seem
> reasonable? If so, advice on how to accomplish this would be most welcome.
>

Remember that your threads are sitting in a loop doing nothing. ffmpeg
is running in a completely separate process. All you are doing in the
thread is monitoring that process. It's not immediately clear that you
really need a thread here at all. You could launch the process in line
and use a timer to check on their completion status.

--
Tim Roberts, ti...@probo.com
Providenza & Boekelheide, Inc.

Olivia Waring

unread,
Apr 24, 2015, 8:46:44 AM4/24/15
to wxpytho...@googlegroups.com
Hi Tim,

Thank you so much for your thorough reply, and apologies for the delay in my response. This was hugely helpful: I will put your suggestions into effect and follow up soon.

Thanks very much again,

Olivia Waring
NPR Labs

James Scholes

unread,
Apr 24, 2015, 1:20:10 PM4/24/15
to wxpytho...@googlegroups.com
Olivia Waring wrote:
> I have attached an abridged version of my program, which defines
> classes for the AnalysisThread, the AdjustThread, and the
> MainWindow.

As an aside, as you are subclassing Thread, you can set your own
parameter list for __init__. This code:

def __init__(self,args):
Thread.__init__(self)
self.file = args[0]
self.index = args[1]
self.IL = args[2]
self.TP = args[3]
self.SP = args[4]

Can be made a bit more Pythonic:

def __init__(self, file, index, IL, TP, SP, *args, **kwargs):
Thread.__init__(self)
self.file = file
self.index = index
self.IL = IL
self.TP = TP
self.SP = SP

Same for your AnalysisThread class.
--
James Scholes
http://twitter.com/JamesScholes
Reply all
Reply to author
Forward
0 new messages