[Tutor] Changing instance attributes in different threads

Kent Johnson kent37 at tds.net
Wed Feb 8 19:47:39 CET 2006


Michael Lange wrote:
> On Wed, 08 Feb 2006 08:37:18 -0500
> Kent Johnson <kent37 at tds.net> wrote:
>>child thread 2:
>>
>>         while self.recording:
>>             data = self.rec_queue.get()
>>             for d in data:
>>                 self._waveobj.writeframesraw(d)# write data to file
>>
> 
> Thanks Kent,
> 
> the problem with Queues is that Queue.get() returns only one item at a time, but I found that depending
> on cpu load and disk usage hundreds of data fragments may accumulate into the recording buffer, so in the "writer"
> thread I would have to use something like (and similar in the get_peaks() method):
> 
>     while self.recording:
>         data = []
>         while not self.rec_queue.empty():
>             try:
>                data.append(self.rec_queue.get(block=0))
>             except Queue.Empty:
>                break
>         for d in data:
>             self._waveobj.writeframesraw(d)
> 
> I am not sure if this approach is more robust than the one that uses Condition() objects,
> however I don't think the code looks cleaner.

I don't understand why this is better than my code. It's a little 
different - you get all the data, then write all the data; I get a 
little, write a little - but since you are writing one datum at a time 
in both cases, I don't know why it would make much difference.

You should be able to take the try/except out of your version, since 
this code is the only consumer from the Queue, if queue.empty() is 
false, queue.get() should succeed.

In the vu meter thread I can see you might want to consume a minimum 
length of data but again that doesn't seem so hard.

OTOH your latest code looks OK too, this was just a suggestion.

>>>This *seems* to work, however it looks like this code does not separate properly the gui from the child
>>>threads which everyone says should be avoided in any case.
>>
>>I don't understand your concern here.
>>
> Maybe it is just because I have not fully understood how the Condition objects work; what I had in mind are
> warnings like this one (from http://www.astro.washington.edu/owen/TkinterSummary.html):
> 
> All Tkinter access must be from the main thread (or, more precisely,
the thread that called mainloop).

OK, yes. What this means is that any code that changes the state of the 
GUI should be called from the main thread. In your case, that means that 
the thread that updates the vu meter must be the main thread. If you are 
calling get_peaks() from a scheduled Tkinter task (scheduled with 
after() or after_idle()) you will be fine.

One way this problem comes up is if you have started a thread to run a 
long-running task and you want to update a status bar in the GUI. You 
can't update the GUI directly from the worker thread, you have to pass 
the status info back into the main thread somehow.

Kent



More information about the Tutor mailing list