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