Something needs to happen with shared, and soon.

Michel Fortin michel.fortin at michelf.ca
Sat Nov 17 05:22:23 PST 2012


On 2012-11-16 18:56:28 +0000, Dmitry Olshansky <dmitry.olsh at gmail.com> said:

> 11/16/2012 5:17 PM, Michel Fortin пишет:
>> In case you want to protect two variables (or more) with the same mutex.
>> For instance:
>> 
>>      Mutex m;
>>      synchronized(m) int next_id;
>>      synchronized(m) Object[int] objects_by_id;
>> 
> 
> Wrap in a struct and it would be even much clearer and safer.
> struct ObjectRepository {
> 	int next_id;
> 	Object[int] objects_by_id;
> }
> //or whatever that combination indicates anyway
> synchronized ObjectRepository objeRepo;

I guess that'd be fine too.


> If we made a tiny change in the language that would allow different 
> syntax for passing delegates mine would shine. Such a change at the 
> same time enables more nice way to abstract away control flow.
> 
> Imagine:
> 
> access(object_by_id){
> 	...	
> };
> 
> to be convertible to:
> 
> (x){with(x){
> 	...
> }})(access(object_by_id));
> 
> More generally speaking a lowering:
> 
> expression { ... }
> -->
> (x){with(x){ ... }}(expression);
> 
> AFIAK it doesn't conflict with anything.
> 
> Or wait a sec. Even simpler idiom and no extra features.
> Drop the idea of 'access' taking a delegate. The other library idiom is 
> to return a RAII proxy that locks/unlocks an object on 
> construction/destroy.
> 
> with(lock(object_by_id))
> {
> 	... do what you like
> }
> 
> Fine by me. And C++ can't do it ;)

Clever. But you forgot to access the variable somewhere. What's its 
name within the with block? Your code would be clearer this way:

	{
		auto locked_object_by_id = lock(object_by_id);
		// … do what you like
	}

And yes you can definitely do that in C++.

I maintain that the "synchronized (var)" syntax is still much clearer, 
and greppable too. That could be achieved with an appropriate lowering.


>>> The key point is that Synchronized!T is otherwise an opaque type.
>>> We could pack a few other simple primitives like 'load', 'store' etc.
>>> All of them will go through lock-unlock.
>> 
>> Our proposals are pretty much identical. Your works by wrapping a
>> variable in a struct template, mine is done with a policy object/struct
>> associated with a variable. They'll produce the same code and impose the
>> same restrictions.
> 
> I kind of wanted to point out this disturbing thought about your 
> proposal. That is a lot of extra syntax and rules added buys us very 
> small gain - prettier syntax.

Sometime having something built in the language is important: it gives 
first-class status to some constructs. For instance: arrays. We don't 
need language-level arrays in D, we could just use a struct template 
that does the same thing. By integrating a feature into the language 
we're sending the message that this is *the* way to do it, as no other 
way can stand on equal footing, preventing infinite reimplementation of 
the concept within various libraries.

You might be right however than mutex-protected variables do not 
deserve this first class status.


>> Built-in shared(T) atomicity (sequential consistency) is a subject of
>> debate in this thread. It is not clear to me what will be the
>> conclusion, but the way I see things atomicity is just one of the many
>> policies you may want to use for keeping consistency when sharing data
>> between threads.
>> 
>> I'm not trilled by the idea of making everything atomic by default.
>> That'll lure users to the bug-prone expert-only path while relegating
>> the more generally applicable protection systems (mutexes) as a
>> second-class citizen.
> 
> That's why I think people shouldn't have to use mutexes at all.
> Explicitly - provide folks with blocking queues, Synchronized!T, 
> concurrent containers  (e.g. hash map) and what not. Even Java has some 
> useful incarnations of these.

I wouldn't say they shouldn't use mutexes at all, but perhaps you're 
right that they don't deserve first-class treatment. I still maintain 
that "syncronized (var)" should work, for clarity and consistency 
reasons, but using a template such as Synchronized!T when declaring the 
variable might be the best solution.


-- 
Michel Fortin
michel.fortin at michelf.ca
http://michelf.ca/



More information about the Digitalmars-d mailing list