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

Reply via email to