How to initialize a globle variable nicely and properly?

Rubn where at is.this
Sat Dec 15 03:42:30 UTC 2018


On Saturday, 15 December 2018 at 02:54:55 UTC, Heromyth wrote:
> We have a module including many globle variables which are 
> needed to be initialized firstly in "shared static this() {}", 
> see here 
> https://github.com/huntlabs/hunt/blob/master/source/hunt/time/Init.d.
>
> The problem is that these variables are not always initialized 
> firstly when are referenced by some others moudles in "static 
> this() {}". Here is a demo to illustrate it.
>
> //////////////////
> // module A
> //////////////////
> module test.A;
>
> import std.stdio;
> import core.thread;
> import core.time;
>
> class A {
>     __gshared int sharedField;
>
>     shared static this() {
>         writeln("running A in shared static this(), 
> sharedField=", sharedField);
>
>         Thread th = new Thread(() {  });
>         th.start();
>
>         Thread.sleep(100.msecs);
>         sharedField = 2;
>         writeln("running A done in shared static this(), 
> sharedField=", sharedField);
>     }
>
>     static this() {
>         writeln("running A in static this(), sharedField=", 
> sharedField);
>     }
> }
>
> //////////////////
> // module B
> //////////////////
> module test.B;
>
> import test.A;
> import std.stdio;
> import core.thread;
>
> shared static this() {
>     writeln("running in shared static this() from B");
> }
>
> class B {
>     shared static this() {
>         writeln("running B in shared static this(), 
> sharedField=", A.sharedField);
>     }
>
>     static this() {
>         // bug is here
>         writeln("running B in static this(), sharedField=", 
> A.sharedField);
>     }
> }
>
> //////////////////
> // module main
> //////////////////
> import std.stdio;
>
> import test.A;
> import core.thread;
>
> void main()
> {
> 	writeln("running in main.");
> }
>
> //////////////////
> // output
> //////////////////
> Running ./demo
> running A in shared static this(), sharedField=0
> running A in static this(), sharedField=0
> running B in static this(), sharedField=0  // bug is here
> running A done in shared static this(), sharedField=2
> running in shared static this() from B
> running B in shared static this(), sharedField=2
> running A in static this(), sharedField=2
> running B in static this(), sharedField=2
> running main.
>
>
> ====================
> You can see the sharedField is 0 in B's static this() at first. 
> If Thread is disabled to run in shared static this(), this 
> problem seems to be fixed.
>
> Some related bugs:
> 1) https://issues.dlang.org/show_bug.cgi?id=6114
> 2) https://issues.dlang.org/show_bug.cgi?id=4923

The problem here is that you are creating a new thread in the 
`shared static this()`.

     shared static this() {
         writeln("running A in shared static this(), 
sharedField=", sharedField);
         Thread th = new Thread(() {  }); // Calls `static this()` 
including B's `static this()`
         th.start();
         Thread.sleep(100.msecs);
         sharedField = 2;
         writeln("running A done in shared static this(), 
sharedField=", sharedField);
     }

     static this() {
         writeln("running A in static this(), sharedField=", 
sharedField);
     }

Creating a new thread causes those thread's constructor `static 
this()` to be called. You need to create your threads somewhere 
else or have the values be initialized before the threads are 
created.


More information about the Digitalmars-d-learn mailing list