Proposals: Synchronization
Regan Heath
regan at netwin.co.nz
Mon Jul 24 16:05:33 PDT 2006
On Tue, 25 Jul 2006 07:19:27 +0930, Kent Boogaart
<kentcb at internode.on.net> wrote:
>> This would make this currently legal syntax illegal:
>>
>> void fn() {
>> synchronized {
>> // stuff
>> }
>> }
>>
>> ie. where the synchronization object is implicit. I suppose its value
>> is
>> debatable, but I think it's sufficiently useful that I wouldn't want it
>> to
>> be illegal.
>>
>
> I see that as a good thing, though. That is because the implicit syntax
> is
> locking on this (I assume), which - as discussed - is a bad thing.
I'm not sure I agree that this "is a bad thing". I have done lots of
multithreaded programming in C where you lock a seperate object (a mutex)
to the thing to which you want to synchronize access. I have also done
some (not a huge amount) of Java proghamming where I locked the object
itself. I can't say that I got less deadlocks in C, than I did in Java.
I very much prefer not having to declare, create and use a seperate object
when I can just lock the thing I want to synchronize.
In my experience deadlocks occur whenever 2 or more pieces of code lock 2
or more objects and where each piece of code does it in a different order.
eg.
[thread1]
lock A
..thread swap occurs..
lock B
[thread2]
lock B
..thread swap occurs..
lock A
If thread1 locks A then the CPU swaps threads and thread2 locks B .. you
have a deadlock. Neither thread can progress. If, however, you always lock
in a specific order i.e. A then B always, you can't get a deadlock (in my
experience).
So, rather than seperating the object being locked (the mutex/lock class)
from the object being synchronized, which just seems like bad design to
me, and IMO doesn't actually do anything to solve the problem, what about
some idea to ensure the order in which things are locked?
Off the top of my head.. (and this is something a threading/locking
library could do..)
1. Give each object being locked a priority:
object1: 0
object2: 1
object3: 2
object4: 3
2. If a lock is required on an object and the thread already has a lock on
an object with a higher priority, release the lock on the higher priority
object, obtain the new lock, and then re-obtain the higher priority lock.
Example:
If thread A locks object2, then locks object1, we release the lock for
object1 before obtaining the lock on object2, then we re-obtain the lock
on object2. So, using our previous example:
[priority]
lockA: 0
lockB: 1
[thread1]
lock A
..thread swap occurs..
lock B
[thread2]
lock B
..thread swap occurs..
lock A
thread1 obtains lock A {thread swap} thread2 obtains lock B, thread2
requests lock A, we release lock B (higher priority than A), wait for A
(which is locked by thread1 already) {thread swap}, thread1 obtains lock
B, continues.. releases locks.. {thread swap} thread2 obtains lock A,
thread2 asks for and obtains lock B..
and like magic.. no more deadlocks ;)
Regan
More information about the Digitalmars-d
mailing list