[Python-Dev] deja-vu .. python locking

"Martin v. Löwis" martin at v.loewis.de
Mon Sep 18 22:21:51 CEST 2006


Martin Devera schrieb:
> It is based on assumption that an object is typicaly used by single 
> thread. You must lock it anyway just for case if another thread steps
> on it. The idea is that each object is "owned" by a thread. Owner can
> use its objects without locking. If a thread wants to use foreign
> object then it has to wait for owning thread to go to some safe place
> (out of interpreter, into LOCK of other object..). It is done by
> per-thread lock and it is neccessary because owner does no locking, 
> thus you can be sure that nobody it using the object when former
> owner is somewhere out of the object.

Ah, I think I understand now. First the minor critique: I believe
the locking algorithm isn't thread-safe:

  while (ob->owner_thread != self_thread()) {
	 unlock_mutex(thread_mutex[self_thread()])
	// wait for owning thread to go to quiscent state
	 lock_mutex(thread_mutex[ob->owner_thread])
	 ob->owner_thread = self_thread()
	 unlock_mutex(thread_mutex[ob->owner_thread])
	 lock_mutex(thread_mutex[self_thread()])
  }

If two threads are competing for the same object held by a third
thread, they may simultaneously enter the while loop, and then
simultaneously try to lock the owner_thread. Now, one will win,
and own the object. Later, the other will gain the lock, and
unconditionally overwrite ownership. This will cause two threads
to own the objects, which is an error.

The more fundamental critique is: Why? It seems you do this
to improve efficiency, (implicitly) claiming that it is
more efficient to keep holding the lock, instead of releasing
and re-acquiring it each time.

I claim that this doesn't really matter: any reasonable
mutex implementation will be "fast" if there is no lock
contention. On locking, it will not invoke any system
call if the lock is currently not held (but just
atomically test-and-set some field of the lock); on
unlocking, it will not invoke any system call if
the wait list is empty. As you also need to test, there
shouldn't be much of a performance difference.

Regards,
Martin


More information about the Python-Dev mailing list