On Tue, 07 Feb 2006 06:02:45 -0500 Kent Johnson <[EMAIL PROTECTED]> wrote:
> > One way to make this code thread-safe is to use a threading.Condition() > instead of a boolean variable: > > thread 1 does: > > self.lock.acquire() > if condition: > self.name = 'bob' > else: > self.name = 'mike' > self.lock.release() > > thread 2 does: > > self.lock.acquire() > n = self.name > self.lock.release() > if n == 'bob': > <do something> > else: > <do something else> > > If this is the only communication or synchronization between the two > threads I don't think the lock is needed at all - thread 2 is presumably > in a loop and thread 1 is controlling the behaviour of the loop > asynchronously. If there is some other kind of synchronization between > the loops, and thread 2 is only supposed to run once for each setting of > self.name in thread 1, you could use Condition.wait() and > Condition.notify() to do the synchronization. > Thanks Kent, In fact I have three threads, a main gui thread and two child threads. Child thread 1 reads data from the soundcard and appends these data to two lists which I use as recording buffer. The data from list 1 are used by the gui thread to draw a vumeter, the data from list 2 are written to the target file. So the communication between the threads occurs when the gui thread resp. child thread 2 read and empty the buffer lists to process the data. So my functions currently (with boolean "locks") look like: gui thread (this function is called periodically by Tkinter): def get_peaks(self): if self.vu_locked: return None self.vu_locked = 1 data = [x for x in self.vubuffer] self.vubuffer = [] self.vu_locked = 0 if not data: return None left, right = 0, 0 for d in data: left = max(audioop.max(audioop.tomono(d, 2, 1, 0), 2), left) right = max(audioop.max(audioop.tomono(d, 2, 0, 1), 2), right) return left, right thread 1: vubuffer = [] recbuffer = [] while self.running: data = self._audioobj.read(self._fragsize)# read data from soundcard vubuffer.append(data) if not self.vu_locked: self.vu_locked = 1 self.vubuffer += vubuffer vubuffer = [] self.vu_locked = 0 if self.recording: recbuffer.append(data) if not self.rec_locked: self.rec_locked = 1 self.recbuffer += recbuffer recbuffer = [] self.rec_locked = 0 thread 2: while self.recording: # wait a moment until there is something in the buffer to be written time.sleep(0.1) if not self.rec_locked: self.rec_locked = 1 data = [x for x in self.recbuffer] self.recbuffer = [] self.rec_locked = 0 for d in data: self._waveobj.writeframesraw(d)# write the data to a file So I think I need two Condition objects here; it is most important here that thread 1 does not block to minimize the risk of recording buffer overruns, but from reading the docs I am not sure about the correct procedure. So if I change self.rec_locked and self.vu_locked from the code above to be Condition objects is it correct to do: thread 1: vubuffer = [] recbuffer = [] while self.running: data = self._audioobj.read(self._fragsize)# read data from soundcard vubuffer.append(data) if self.vu_locked.acquire(blocking=0): self.vubuffer += vubuffer vubuffer = [] self.vu_locked.release() if self.recording: recbuffer.append(data) if self.rec_locked.acquire(blocking=0): self.recbuffer += recbuffer recbuffer = [] self.rec_locked.release() thread 2: while self.recording: # wait a moment until there is something in the buffer to be written time.sleep(0.1) data = [] if self.rec_locked.acquire(blocking=0): data = [x for x in self.recbuffer] self.recbuffer = [] self.rec_locked.release() for d in data: self._waveobj.writeframesraw(d)# write the data to a file Thanks Michael _______________________________________________ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor