On Wednesday, 8 July 2015 at 10:49:05 UTC, tcak wrote:
On Wednesday, 8 July 2015 at 10:10:58 UTC, Jonathan M Davis
wrote:
On Wednesday, 8 July 2015 at 09:54:01 UTC, ketmar wrote:
On Wed, 08 Jul 2015 09:43:38 +0000, wobbles wrote:
Ok, so we should prioritise using 'shared' over __gshared as
much as possible. Good to know!
only `shared` is PITA...
The primary advantage of shared is that it allows most
everything to be thread-local.
Though arguably, shared _should_ be a bit of a pain, since its
usage should normally be very restricted. But we do need to
revisit shared and figure out what we want/need to do with it.
Synchronized classes as described in TDPL were never even
implemented (though I contest that they really make shared
usable in any kind of sane way; I really don't see how you can
do anything other than really basic stuff with shared without
requiring that the programmer deal with the locks and casting
properly on their own). So, more work needs to be done there
even if it's figuring out what shared _isn't_ going to be
doing.
Really though, one of the bigger problems is dealing with
allocation and deallocation of shared objects and passing
objects across threads, since we keep wanting to be able to do
stuff like have thread-specific allocators, but the way shared
currently works doesn't actually allow for it. :|
Regardless, while I would very much like to see shared
properly ironed out, I'm _very_ grateful that thread-local is
the default in D. It's just so much saner.
- Jonathan M Davis
I still couldn't have found my answer though. I have three
different use cases, one is missing in the language.
1. Thread-local object.
2. Shared, but implemented as not to be synchronised.
3. Shared, and implemented to be synchronised.
There is no simple way to design a class, so that you can
implement it for points 2 and 3. The only way is to use
_gshared with point one to solve it.
I use shared in many of my classes. Thus I experience different
situations.
By using __gshared, you're throwing away the compiler's help, and
it's _much_ more likely that you're going to write code which
causes the compiler to generate incorrect machine code, because
it's assuming that an object is thread-local when it's not.
Generally what you have to do with shared is lock on a mutex,
cast away shared on the object you want to operate on, do
whatever you're going to do with it, and then release the lock
after there are no more thread-local references to the shared
object. And that's basically what you normally should be doing in
C++ code except that you don't have to cast away shared, because
C++ doesn't have it.
I know that there are a number of people who get frustrated with
shared and using __gshared instead, but unless you fully
understand what you're doing and how the language works, and
you're _really_ careful, you're going to shoot yourself in the
foot it subtle ways if you do that.
- Jonathan M Davis