[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