synchronized - shared but actually useful

FeepingCreature feepingcreature at gmail.com
Wed Oct 31 09:36:22 UTC 2018


On Wednesday, 31 October 2018 at 09:04:43 UTC, Jonathan M Davis 
wrote:
>> Everything in the class has to be synchronized. I'm not sure 
>> where I said differently.
>
> You were talking about marking individual fields and variables 
> as synchronized rather than simply marking the entire class as 
> synchronized.

Sorry- I see your point. There is indeed no reason for 
non-synchronized fields. Strike that from the proposal. I'm not 
sure why I had it in there.

> The part directly embedded in the class and which therefore 
> cannot possibly escape. Unlike regular classes, synchronized 
> classes do not allow direct access to their member variables - 
> even from anything else in the same module - in order to be 
> able to provide that guarantee. If you don't have your own copy 
> of TDPL, I'd suggest reading the concurrency chapter which is 
> available for free online, since it talks about synchronized 
> classes:
>
> http://www.informit.com/articles/article.aspx?p=1609144
>

Wow, I straight up hadn't known that synchronized classes were a 
thing. I think it's because synchronized is not listed as an 
attribute on the Attributes page, but rather as a separate syntax 
on the Class page.

>> And yet, there's no way to even *state* that the Thread 
>> constructor must not take a delegate that can access unshared 
>> data, and none of the current proposals list one. Should we 
>> demand that only shared data can be passed to new threads? 
>> That's going to limit their usefulness. With synchronized, we 
>> can deprecate the delegate constructor, then pass the thread 
>> data as synchronized objects to a pure function, thereby 
>> actually guaranteeing thread safety.
> 
> [ snip std.concurrency which we're not using ]
> 
> Thread is a bit different, but the concept is basically the 
> same. Conceptually, it's being passed off to another thread, so 
> it really should be shared or immutable, but C doesn't actually 
> _have_ shared (hence __gshared), so everything involved _has_ 
> to be @trusted internally. Looking at Thread's constructor, 
> having it take a delegate probably isn't a problem, but what 
> _is_ a problem is the fact that it's @safe. I don't know how we 
> can reasonably fix that without breaking code, but it's 
> definitely a problem. All data passed through that delegate 
> must either be shared or it must be the only reference to that 
> data so that when it ends up on that new thread, and it's 
> thread-local, no other thread has reference to it, and it 
> really is properly thread-local. That constructor can't 
> guarantee that. It's up to the programmer to guarantee that. 
> So, it needs to be @system.
>
> If we could somehow require that the delegate only accepted 
> shared data, then we could reasonably make the constructor 
> @safe, but since AFAIK, that's not possible, it needs to be 
> @system.
>
> - Jonathan M Davis

There doesn't seem to be a trait to detect a synchronized class. 
Having learnt that synchronized classes are actually mostly 
implemented (how did I not know this! Though I still think the 
fact that they can be impure is an issue, but that's statically 
checkable at least), it seems like it should at least be possible 
to require that the Thread runner only accesses shared data, by 
limiting it to take a pure function that only has 
synchronized-class parameters. Well, it would be, if there was a 
trait for synchronized classes, but that seems like it'd be much 
easier to add.


More information about the Digitalmars-d mailing list