www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - shared Duration math

reply "knutaf" <a b.com> writes:
Hello,

My question probably reveals a dangerous lack of understanding of 
the language, but perhaps someone can help me understand why the 
following code works and doesn't work in the indicated places.

Secondarily, does anyone know a really good article that explains 
how "shared" works, especially shared as a qualifier on member 
functions? And what it even means to be a shared local variable?

import std.stdio;
import core.time;
import std.datetime;

void main()
{
     shared Duration sd1 = dur!"seconds"(5);
     shared Duration sd2 = dur!"seconds"(6);
     Duration d3 = dur!"seconds"(7);

     //Duration d4 = sd1 + sd2; // error, incompatible types
     //Duration d4 = sd1 + d3; // error, incompatible types
     //Duration d4 = (cast(Duration)sd1) + (cast(Duration)sd2); // 
error, template deduction

     // compiles, but how is the implicit cast allowed, when 
explicit fails above?
     Duration d5 = sd1;
     Duration d6 = sd2;
     Duration d7 = d5 + d6;
}
Jun 06 2014
parent Jonathan M Davis via Digitalmars-d <digitalmars-d puremagic.com> writes:
On Sat, 07 Jun 2014 02:31:19 +0000
knutaf via Digitalmars-d <digitalmars-d puremagic.com> wrote:

 Hello,

 My question probably reveals a dangerous lack of understanding of
 the language, but perhaps someone can help me understand why the
 following code works and doesn't work in the indicated places.

 Secondarily, does anyone know a really good article that explains
 how "shared" works, especially shared as a qualifier on member
 functions? And what it even means to be a shared local variable?

 import std.stdio;
 import core.time;
 import std.datetime;

 void main()
 {
      shared Duration sd1 = dur!"seconds"(5);
      shared Duration sd2 = dur!"seconds"(6);
      Duration d3 = dur!"seconds"(7);

      //Duration d4 = sd1 + sd2; // error, incompatible types
      //Duration d4 = sd1 + d3; // error, incompatible types
      //Duration d4 = (cast(Duration)sd1) + (cast(Duration)sd2); //
 error, template deduction

      // compiles, but how is the implicit cast allowed, when
 explicit fails above?
      Duration d5 = sd1;
      Duration d6 = sd2;
      Duration d7 = d5 + d6;
 }

A shared local variable is mostly useless, and shared in general is a bit of a pain. It'll probably get some sort of overhaul in the future, but for now, if you want to use shared, what you have to do is protect access to the shared variable with a lock (be it a mutex or synchronized block or whatever), cast away shared on it, use it with normal functions, make sure that there are no non-shared references to the same data, and release the lock. shared is designed specifically so that it doesn't work with normal functions, because that would prevent normal functions from being optimized based on the fact that the variables are thread-local as well as due to the fact that shared code should generally be segregated from normal code. So, for now, you'd do something like auto lock = new Object; auto foo = new shared int*; synchronized(lock) { auto unshared = cast(int*)foo; // do something with unshared // make sure that no references to unshared exist } But that is a bit ugly, and it's not terribly safe, since it requires the programmer to get it right. Ideally, we'd have some way for the compiler to determine that it can implicitly remove shared within a section of code so that you can do operate on it as thread-local, but we dont' have anything like that right now. In general though, the idea is to use std.concurrency or std.parallelism for sharing data across threads rather than using shared. So, the need for share should be fairly rare. - Jonathan M Davis
Jun 06 2014