April 03, 2019 Re: shared - no read/write access | ||||
---|---|---|---|---|
| ||||
Posted in reply to Kagamin | On Tuesday, April 2, 2019 5:37:20 AM MDT Kagamin via Digitalmars-d wrote: > On Sunday, 31 March 2019 at 07:12:08 UTC, Jonathan M Davis wrote: > > If the compiler can guarantee thread-safety, then there shouldn't be a problem, and nothing needs to be made illegal, but that's usually not the case. The primary exception would be stuff like atomics, and that's typed with shared, so you can pass shared variables to them. And it's not a problem, because thread-safety is guaranteed. > > False sense of thread safety already? Code is not magically thread safe because it uses atomics, they are only a tool. Thread safety is a global property and can't be easily provided on low level alone. But added churn can increase mistakes because of increased cognitive load. Atomics guarantee that the read/write operations are thread-safe, but no they obviously can't guarantee things like that a set of interrelated variables whose values should be kept in sync are actually protected against multiple threads mucking with them at once. So, maybe a better way to put it is that the compiler won't allow operations that it can't guarantee are atomic (or which are marked shared). > > In the cases where synchronization _is_ needed, then those operations should be illegal, requiring the programmer to protect the object appropriately and then cast away shared to operate on it while it's protected. That way, nothing marked as shared is violating thread-safety, and the code where there is a risk of violating thread-safety is @system. So, it becomes fairly easy to grep for the portions of the code where you need to worry about threading bugs. > > @safe code might be disallowed to access shared data, that's understandable, but like for @system, it's difficult to provide protection for shared code that can pull its weight. > > Also greppability implies that casting away shared is not really inevitable, it's needed if you want to apply algorithm that was written for thread local data, but keeping data and methods as shared will help communicate that it's not an ordinary thing happening here (a use case for private shared methods). Greppability just means that you can easily find the code in question, and between the keywords shared, cast, @trusted, and @system, it should be easy to quickly narrow down the code that involves casting away shared and thus find the code that has to be closely examined for threading issues. And code involving atomics is easily greppable - and thus easily findable - for the same reason. And no, it shouldn't be the case that everything using a shared variable has to constantly cast away shared to do anything with it, because those operations can be encapsulated in functions - a prime example of that being an object that has its own mutex to protect its data. Nothing using the object would need to cast away shared, but internally, that's exactly what the object would need to do in order to actually mutate the data. That's already true to an extent, because some read/write operations are illegal on shared objects and have been for some time. The problem is that they aren't all illegal. So, instead of the whole thing being set up so that you clearly have to cast away shared to mutate data, you end up only having to cast it away some of the time, just increasing the annoyance factor. Either we need to go all the way and make all non-atomic read/write operations illegal on shared data or just give up on shared providing any protections at all beyond ensuring that code not involving casts can't make the type system treat shared data as thread-local or vice versa. - Jonathan M Davis |
Copyright © 1999-2021 by the D Language Foundation