Sharing in D

Steven Schveighoffer schveiguy at yahoo.com
Fri Aug 1 07:17:46 PDT 2008


"Walter Bright" wrote
> Steven Schveighoffer wrote:
>> "Walter Bright" wrote
>>> Nearly all global data is assumed to be and treated as if it were 
>>> unshared. So making unshared the default is the right solution. And 
>>> frankly, if you're using a lot of global variables, you might want to 
>>> reevaluate what you're doing. Lots of global variables is the 80's style 
>>> of programming :-)
>> I have no idea where you came up with this.  To me global means shared. 
>> Global means the world can see it, meaning that it's shared between all. 
>> Even VB.net uses 'Shared' as the keyword to mean 'global'
>
> The idea is that encapsulation is better, and having something shared 
> between everyone violates encapsulation. When you have a global variable 
> 'int x' that everyone can read and write to, and there's a bug, you have 
> the whole program to search for that bug. The principle of encapsulation 
> is that each chunk of data is visible only to the code that needs to see 
> it, and no more.

So if I write:
shared int x;

As a global variable, how does this help encapsulation?  In the current 
model, if you need shared data, you use global variables.  If you don't need 
shared data, use member or stack variables.  My point is that what you will 
have done is just made the person who wants a global variable write 'shared' 
in front of it.  I don't see how this helps him protect the variable at all. 
It just seems like you are enforcing something that already can be enforced.

> (Programming languages started out with everything being global data, and 
> has moved away from that ever since.)

I'm not advocating using global variables over stack or member variables. 
All I'm saying is that this 'shared/unshared' model doesn't seem to me like 
it will eliminate the need for threading constructs, or even help with it.

>> Yeah, because all us cowboys don't like your kind.  Maybe we need to get 
>> us a rope and have a lynchin.  Seriously, how can you say that the 
>> current threadding tools are 'uncontrolled' (i.e. wild west)?
>
> Because of the common multithreaded bug 
> http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html
> for one example. There is no threading tool I'm aware of that can prevent 
> or detect such bugs.

As described on that page, the problem was fixed with JDK 5, and can be 
solved using the volatile modifier.

>> I spend lots of time thinking about multithreadded issues, and make sure 
>> my software works properly.  I think the level of quality for threadding 
>> issues depends on the coder, not the tools.
>
> I believe the tools can make it easier.

I do too.  But I don't see this one being that tool.

>> In the case of shared/unshared, it's not going to change anything, except 
>> now I have to declare things I didn't have to declare before.  I.e. 
>> having shared/unshared is going to be just as wild as before.
>
> Why? First of all, unshared data isn't going to have sequential or sync 
> issues, by definition. Already, you've cut the problem domain down by a 
> huge chunk. Next, shared data access will come with fences or sync. That 
> isn't going to guarantee no deadlocks, but it will guarantee sequential 
> consistency, and at the very least will dramatically cut the problem 
> domain down.

Are you saying that there will be an automatic notion by the compiler that 
implements the fences, or that I have to add them on top?  If the former, 
then I don't remember reading that in the article, and that does sound 
promising.

>
>
>> Except now instead of the compiler helping you, you have pushed aside 
>> that help and said 'I know what I'm doing'.  Oops, back to the wild west 
>> :)
>
> If you want the wild west, you have it, if you want compiler help instead, 
> you got it. How is that worse than C++ or Java, where you always have the 
> wild west and no help at all?

What I'm saying is that if you have to cast just to get something working, 
you have defeated the system.  I'm not saying that you are back to the wild 
west *by choice*, I'm saying you will most likely end up having to do that 
just to get it to work.  I'm thinking of many cases where you have to use 
old code, or old libraries that don't have this feature, or code written by 
someone unaware of the details.

>>> True, but having it happen implicitly is even worse, because there's no 
>>> indication that it is happening.
>>
>> dmd mycode.d
>> Error: when calling foo(shared int *), cannot pass int *
>>
>> edit mycode.d, cast to shared int *
>>
>> OK, now it works :)  Probably without any problems, because the compiler 
>> has no idea whether I'm going to change it in another thread.  Hell, I 
>> might not even HAVE more than one thread!
>>
>> But the result is, we're back to the same model as before.  And now I 
>> have to cast everything.   Annoying.
>
> Non-shared can be implicitly cast to shared, as that is always safe. Just 
> not the other way.

How is that possible?

shared int *x;

void foo(shared int *y)
{
    x = y;
}

int *x2;

void bar()
{
    foo(x2);
}

After calling bar, isn't x2 now both shared (as x) and unshared at the same 
time?  I think you need casts for both ways.

I think shared/unshared is analogous to mutable/invariant.  There is no 
implicit cast.

>
>
>> Please let me decide whether I'm far better off.
>
> Ok. D offers both - and for the guy maintaining your code, there'll at 
> least be clear indications of where to look for the source of elusive 
> threading bugs.

All I was saying with that comment is the notion that 'Walter knows best' is 
not a convincing argument.

>
> Optlink currently has a threading bug in it. I have no idea where to look 
> for it in the source code.

Threading problems are very difficult to find.  I don't think the 
shared/unshared model will help with that, especially since most likely you 
will have to break it to get things working.

I generally can only find multithreading issues with lots of logging, and 
running through potentially offending code in my head.

I think that this idea has potential, and could possibly lead to something 
that is helpful.  The thinking is in the right direction.  But I'm not 
convinced that this incarnation will be helpful.  I'd have to see examples 
of how this would be useful to understand it better.

And please PLEASE make it backwards compatible.  I don't see any reason why 
it must be shared that is the tagged value.

-Steve 





More information about the Digitalmars-d mailing list