On Fri, 07 Jan 2011 09:55:33 -0500, Adam Conner-Sax
<adam_conner_...@yahoo.com> wrote:
== Quote from Adam Conner-Sax (adam_conner_...@yahoo.com)'s article
So, I thought I sort of understood "shared" and now I think I don't.
If I have a class:
class foo {
int x;
static int y;
shared static int z;
}
So x is one instance per class and is thread-local?
y is one instance per thread?
z is one instance per application, i.e., global?
If that's true (and I realize it might not be), and I want to
initialize these
variables in constructors, how does that work?
I think
class foo {
...(as before)
this() { x = 2; } // ok
static this() { y = 3; } // is this called once per thread?
shared static this() { z = 3;} // also, okay, called before main
}
but I don't understand what happens with threads and the "static this"
constructor. How/when are the thread-local copies constructed? How do
you
initialize/construct the thread-local static data?
Thanks!
Adam
Nevermind. Answered myself with the following:
import core.thread;
import std.c.stdio;
class foo {
int a;
shared int b;
static int x;
shared static int y;
shared static int[] arr1;
shared static int[] arr2;
this() { a = 1; b=10; }
static this() { x=100; arr1 ~= x; }
shared static this() { y=1000; arr2 ~= y; }
static void A() { x++; y++; }
void B() { a++; b++; }
void report() {
printf("a=%i; b=%i; x=%i; y=%i; arr1.length=%i;
arr2.length=%i\n",a,b,x,y,arr1.length, arr2.length);
}
}
void main()
{
auto f = new foo();
void call_foo_functions() { f.A(); f.B(); f.report(); }
auto tg = new ThreadGroup();
foreach (k; 0..3) {
auto t = new Thread(&call_foo_functions);
tg.add(t);
t.start();
}
tg.joinAll();
printf("back in main: ");
f.report();
}
which output:
a=2; b=11; x=101; y=1001; arr1.length=2; arr2.length=1
a=3; b=12; x=101; y=1002; arr1.length=2; arr2.length=1
a=4; b=13; x=101; y=1003; arr1.length=3; arr2.length=1
back in main: a=4; b=13; x=100; y=1003; arr1.length=3; arr2.length=1
which all makes sense (to me) except a. Why is a acting global? Is it
since it
isn't static so it belongs to the class and there is only one copy of
the class?
Then what makes a and b different?
OK, so here is what is happening :)
call_foo_functions is a delegate, which means it has a frame pointer to
the main function. So all three threads' f is the *same* f (the one
defined in main()).
I would suggest that you move call_foo_functions outside main, and
instantiate an additional f *inside* the function. This would be more
correct.
Incidentally, it appears that this allows untagged sharing (i.e. sharing
data that isn't tagged with shared) I wonder if this issue has been
reported before? Sean?
Also, though maybe it's obvious to everybody else, I think the docs
should explain
someplace that "static this()" gets called once *per thread*. Maybe I
just missed it.
Yes, the documentation is out of date. Could you file a bugzilla report
on this?
-Steve