[Python-bugs-list] [Bug #133665] Race condition in threading (Conditions)
noreply@sourceforge.net
noreply@sourceforge.net
Fri, 23 Feb 2001 00:11:32 -0800
Bug #133665, was updated on 2001-Feb-22 13:15
Here is a current snapshot of the bug.
Project: Python
Category: Threads
Status: Open
Resolution: None
Bug Group: None
Priority: 4
Submitted by: nobody
Assigned to : tim_one
Summary: Race condition in threading (Conditions)
Details: Here is a race condition involving a _Condition() object cond and
a predicate called condition.
Thread A executes:
cond.acquire()
while not condition:
cond.wait() <--
A goes into wait():
waiter = _allocate_lock()
waiter.acquire()
self.__waiters.append(waiter)
saved_state = self._release_save() <--
A finishes that last line and is interrupted by Thread B. A has released
cond's lock, so B continues (who was previously blocked at
cond.acquire()):
cond.acquire()
condition = 1
cond.notifyAll()
cond.release()
Back to A:
if timeout is None:
waiter.acquire() <--
A blocks here and completely misses the notifyAll() call. Even though it
called wait() before notifyAll(), it will now wait indefinatly for the next
notify()/notifyAll() call (which may be never).
I have run into this thread race bug in my program several times. A
POSIX-like atomic operation that releases a mutex and then grabs another
would be very useful here. Any suggestions?
Follow-Ups:
Date: 2001-Feb-23 00:11
By: tim_one
Comment:
You're going to have to work a lot harder to convince me that A can block.
When cond.notifyAll() is executed, *all* the waiters in self.__waiters get
released. It's certain that the waiter W allocated by A is in
self.__waiters at that point, because the append of W was protected by the
condvar lock, and B can't do cond.notifyAll() before it does
cond.acquire().
Therefore W is in self.__waiters when cond.notifyAll() is executed;
therefore cond.notifyAll()'s
for waiter in waiters: waiter.release()
executes W.release() in particular; therefore A's W.acquire() succeeds
sooner or later after that.
IOW, A cannot block on waiter.acquire(), because notifyAll() does
waiter.release().
I agree this *would* be a bug if A could block here, but, as above, I see
no reason to believe that it can.
Have reduced priority, and will close as NotABug tomorrow in the absence of
more info.
-------------------------------------------------------
For detailed info, follow this link:
http://sourceforge.net/bugs/?func=detailbug&bug_id=133665&group_id=5470