Threads, shread and TLS

Adam Conner-Sax adam_conner_sax at yahoo.com
Fri Jan 7 06:55:33 PST 2011


== Quote from Adam Conner-Sax (adam_conner_sax at 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?

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.

Adam


begin 644 TLS_Test.d
M:6UP;W)T(&-O<F4N=&AR96%D.PII;7!O<G0@<W1D+F,N<W1D:6\["@IC;&%S
M<R!F;V\@>PH@"B`@:6YT(&$["B`@<VAA<F5D(&EN="!B.PH*("!S=&%T:6,@
M:6YT('@["B`@<VAA<F5D('-T871I8R!I;G0@>3L*("!S:&%R960@<W1A=&EC
M(&EN=%M=(&%R<C$["B`@<VAA<F5D('-T871I8R!I;G1;72!A<G(R.PH*("!T
M:&ES*"D@>R!A(#T@,3L at 8CTQ,#L@?0H@('-T871I8R!T:&ES*"D@>R!X/3$P
M,#L at 87)R,2!^/2!X.R!]"B`@<VAA<F5D('-T871I8R!T:&ES*"D@>R!Y/3$P
M,#`[(&%R<C(@?CT@>3L@('T*"B`@<W1A=&EC('9O:60 at 02@I('L@>"LK.R!Y
M*RL[('T*("!V;VED($(H*2![(&$K*SL at 8BLK.R!]"B`@=F]I9"!R97!O<G0H
M*2!["B`@("!P<FEN=&8H(F$])6D[(&(])6D[('@])6D[('D])6D[(&%R<C$N
M;&5N9W1H/25I.R!A<G(R+FQE;F=T:#TE:5QN(BQA+&(L>"QY+&%R<C$N;&5N
M9W1H+"!A<G(R+FQE;F=T:"D["B`@?0I]"@H*"G9O:60@;6%I;B at I(`I["@H@
M(&%U=&\@9B`](&YE=R!F;V\H*3L*("!V;VED(&-A;&Q?9F]O7V9U;F-T:6]N
M<R at I('L at 9BY!*"D[(&8N0B at I.R!F+G)E<&]R="@I.R!](`H@(&%U=&\@=&<@
M/2!N97<@5&AR96%D1W)O=7`H*3L*("!F;W)E86-H("AK.R`P+BXS*2!["B`@
M("!A=71O('0@/2!N97<@5&AR96%D*"9C86QL7V9O;U]F=6YC=&EO;G,I.PH@
M("`@=&<N861D*'0I.PH@("`@="YS=&%R="@I.PH@('T*("!T9RYJ;VEN06QL
M*"D["B`@+R\@83TQ/PH@("\O(&(],3,_"B`@+R\@>#TQ,#`_"B`@+R\@>3TQ
M,#`S"B`@<')I;G1F*")B86-K(&EN(&UA:6XZ("(I.PH@(&8N<F5P;W)T*"D[
-"B!](`H@("`@"@H*"@``
`
end


More information about the Digitalmars-d-learn mailing list