shared Duration math

Jonathan M Davis via Digitalmars-d digitalmars-d at puremagic.com
Fri Jun 6 21:06:14 PDT 2014


On Sat, 07 Jun 2014 02:31:19 +0000
knutaf via Digitalmars-d <digitalmars-d at 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


More information about the Digitalmars-d mailing list