synchronized (this[.classinfo]) in druntime and phobos
Regan Heath
regan at netmail.co.nz
Wed May 30 10:40:18 PDT 2012
On Wed, 30 May 2012 18:16:38 +0100, Andrei Alexandrescu
<SeeWebsiteForEmail at erdani.org> wrote:
> On 5/30/12 9:43 AM, Regan Heath wrote:
>> On Wed, 30 May 2012 17:00:43 +0100, Andrei Alexandrescu
>> <SeeWebsiteForEmail at erdani.org> wrote:
>>
>>> On 5/30/12 5:32 AM, Regan Heath wrote:
>>>> On Wed, 30 May 2012 10:21:00 +0100, deadalnix <deadalnix at gmail.com>
>>>> wrote:
>>>>> You don't want to synchronize on ANY object. You want to synchronize
>>>>> on explicit mutexes.
>>>>
>>>> +1 .. this is the key point/issue.
>>>
>>> TDPL's design only allows for entire synchronized classes (not
>>> separate synchronized and unsynchronized methods), which pair mutexes
>>> with the data they protect. This is more restrictive than exposing
>>> mutexes, but in a good way. We use such a library artifact in C++ at
>>> Facebook all the time, to great success.
>>
>> Can you call pass them to a synchronized statement? i.e.
>>
>> TDPLStyleSynchClass a = new TDPLStyleSynchClass();
>> synchronized(a) {
>> }
>
> Yes. Well I recommend acquiring the text! :o)
>
>> ... because, if you can, then you're exposing the mutex.
>
> No.
For the purposes of this thread, and the anti-pattern/problem we're
discussing, you are. It is the combination of synchronized
classes/methods (implicit locking) and external synchronized statements
(explicit locking) which result in the unexpected, accidental, and hard to
see deadlocks we're talking about here.
>>> People shouldn't create designs that have synchronized classes
>>> referring to one another naively. Designing with mutexes (explicit or
>>> implicit) will always create the possibility of deadlock, so examples
>>> how that could happen are easy to come across.
>>
>> True. But in my Example 1
>
> Your example 1 should not compile.
o.. k.. I expected you would get my meaning with the simplified example.
Here you are:
import core.thread;
import std.random;
import std.stdio;
class C
{
synchronized void ccc() { writefln("c.ccc()"); }
}
class D
{
synchronized void ddd() { writefln("d.ddd()"); }
}
shared C c;
shared D d;
void main()
{
c = new shared(C)();
d = new shared(D)();
Thread thread1 = new Thread( &threadFunc1 );
Thread thread2 = new Thread( &threadFunc2 );
thread1.start();
thread2.start();
Thread.sleep(dur!("seconds")(60));
}
void threadFunc1()
{
Random gen = rndGen();
while(1)
{
synchronized(c)
{
printf("threadFunc1 sync(c) %p, obtain d.. %p\n", c, d);
d.ddd();
}
Thread.sleep(dur!("usecs")(gen.front()));
gen.popFront();
}
}
void threadFunc2()
{
Random gen = rndGen();
while(1)
{
synchronized(d)
{
printf("threadFunc1 sync(d) %p, obtain c.. %p\n", d, c);
c.ccc();
}
Thread.sleep(dur!("usecs")(gen.front()));
gen.popFront();
}
}
Runs and deadlocks immediately.
>>> TDPL improves on deadlocks by introducing synchronized statements with
>>> more than one argument, see 13.15.
>>
>> Is there anywhere I can see this online? (for free :p)
>
> http://goo.gl/ZhPM2
Thanks.
R
--
Using Opera's revolutionary email client: http://www.opera.com/mail/
More information about the Digitalmars-d
mailing list