On Monday, 26 November 2018 at 14:28:33 UTC, Steven Schveighoffer
wrote:
Some problems arose:
1. Obviously, this is not the case, as the output is
different, depending on the thread I start the model function.
Yes, unless you declare the model to be shared, there is a copy
made for each thread, independently managed.
2. If I declare the model object inside the main, the compiler
aborts with the message "Aliases to mutable thread-local data
not allowed."
Right, because you are not allowed to pass unshared data
between threads.
3. If I mark the S instance as shared, it works. But I didn't
intend to do this... Is this really how it meant to be?
Let's go over how the data is actually laid out:
Model has NO data in it, so it doesn't really matter if it's
shared or not.
S has a single array of element type D's. There is no static
data in S, so it has no static state (only instance state).
D has a single size_t, which is thread-local,
especially, the size_t is local to an instance of D.
but has a static instance of S in the TYPE.
Right, because to work properly a D instance has to know about
the D's in the array of S
There is not a copy of an S for each D, just a single copy for
each THREAD. If you make this shared, it's a shared copy for
all threads. This means the array inside the shared S will be
shared between all threads too.
This is the point where my headaches begin: I do not need this
level of sharedness, but I don't really care.
What happens when you spawn a new thread is that the
thread-local copy of m is created with Model.init (but it has
no data, so it's not important). A thread-local copy of D.s is
created with S.init (so an empty array). The reason your
assignment of length in main doesn't work is because the init
value is used, not the current value from the main thread.
So yes, you need to make it shared to have the sub-thread see
the changes, if that's what you are after.
As I'm writing the model object as well as all of its
compartments, I can do almost everything... but what I to
avoid is to declare the instances of compartments inside the
model:
They are stored locally to their modules and the single
elements of them have to know about the compound objects, like
with the D and S structs shown.
A static member is stored per thread. If you want a global
that's shared between all threads, you need to make it shared.
But the result may not be what you are looking for, shared can
cause difficulty if your code wasn't written to deal with it
(and a lot of code isn't).
Well, the only reason I use multithreading is this:
https://forum.dlang.org/thread/cfrtilrtbahollmaz...@forum.dlang.org
So, even if my code is not really shared designed, this doesn't
matter, as I wait for "the other" thread to end (or interrupt
it). So, marking the model as shared is already a workaround, for
being able to pass it to another thread, which I don't really
need. However, now, if also all components of the model have to
be marked shared, the workaround has to grow and expands over all
components (?). This is the reason for this question...
-Steve