Michael Lange wrote:
> I have used a boolean to control access to a variable that is used by two
> threads,
> as in this example:
>
> thread 1 does:
>
> while self.locked:
> pass
> self.locked = 1
> if condition:
> self.name = 'bob'
> else:
> self.name = 'mike'
> self.locked = 0
>
> thread 2 does:
>
> while self.locked:
> pass
> self.locked = 1
> n = self.name
> self.locked = 0
> if n == 'bob':
> <do something>
> else:
> <do something else>
>
> I *thought* this would be safe, but now reading this thread I start to doubt.
> Are there any pitfalls I overlooked in this technique?
If the intent is to ensure that only one thread at a time will be in the
code where self.locked == 1, this code will not ensure that.
Test-and-set code needs a lock to be thread safe.
Imagine both threads reach 'while self.locked' when self.locked == 0.
Both threads might finish the while loop before either one sets
self.locked. Then both threads might continue through to 'self.locked =
0' together.
In this case I'm not sure what would happen if the above scenario took
place; it might be harmless. But your lock is definitely not doing what
you think it is.
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.
Kent
_______________________________________________
Tutor maillist - [email protected]
http://mail.python.org/mailman/listinfo/tutor