Shared an non-shared
Jonathan M Davis via Digitalmars-d-learn
digitalmars-d-learn at puremagic.com
Wed Oct 5 00:36:58 PDT 2016
On Tuesday, October 04, 2016 19:22:10 Begah via Digitalmars-d-learn wrote:
> How can I make a method that accepts being called by both a
> shared and non-shared object, to prevent having to copy methods
> and adding a "shared"?
You could templatize them, but really, the idea is that you _don't_ call
much of anything on a shared object. It's not thread-safe to do so unless
it's protected by a mutex or sychronized block. shared is as unwieldy as it
is in part because it's easy to use incorrectly, and most code should not be
using shared at all, because the stuff that actually needs to be shared
across threads is normally pretty minimal. The fact that most operations are
illegal on shared objects prevents misuse. But of course, it leaves the
question of how you go about actually doing anything with a shared object,
since obviously, you're going to do need to do more than just create the
thing.
TDPL talks about synchronized classes where the outer layer of shared gets
automatically cast away within the member functions of the class (since the
compiler can guarantee that only one thread at a time is in the member
functions of the class). However, synchronized classes haven't been
implemented as of yet, and we just have synchronized functions, which do
protect those functions with a mutex, but without requiring that all
functions within the class be synchronized and make it illegal to access the
member variables except via the member functions, the compiler can't cast
away the outer layer of shared, because it can't guarantee that the member
is actually protected by a mutex.
So, the way to solve this is that when you want to operate on a shared
object, you first make sure that it's protected by a mutex (like you would
in a language like C or C++), then you cast away shared to operate on the
object, and then when you're done, you make sure that no non-shared
references to the object exist, and release the mutex. e.g. something like
shared MyClass mySharedObj = getSharedObj();
synchronized(myMutex)
{
auto obj = cast(MyClass)mySharedObj;
// do stuff with obj...
// obj should be the only non-shared reference to the object
// referred to by mySharedObj when the sychronized block exits.
}
So, ultimately, the code is basically the same as what you'd do in C/C++
except that you have to cast away shared to actually do much of anything to
the object. It _is_ unfortunately more error-prone than synchronized classes
would be, because you're forced to do a manual cast, but since we don't
actually have synchronized class, you don't have much choice, and since
synchronized classes would only strip away the outer layer of shared,
there's a halfway decent chance that you'd still need to do something like
this even if we did have synchronized classes.
- Jonathan M Davis
More information about the Digitalmars-d-learn
mailing list