【D语言】共享数据

在D语言中,全局变量和静态变量默认是存储在TLS中的,这意味着不同线程有着不同的变量副本,这一点和其他语言都是不同的

import std.stdio, core.thread;

auto x = 3; // 全局变量默认存储在TLS,这点不同于C/C++

void main()
{
    static y = 3;  // 静态变量同全局变量一样,存储在TLS
    x = 5;
    y = 5;
    writeln("Main Thread: x=", x);
    writeln("Main Thread: y=", x);

    new Thread({ 
        writeln("Child Thread: x=", x); 
        writeln("Child Thread: y=", y);
    }).start();

    Thread.sleep(dur!("seconds")(2));
}

输出

Main Thread: x=5
Main Thread: y=5
Child Thread: x=3
Child Thread: y=3

主线程修改了变量值,而子线程输出却还是初始值,这就证明了全局变量和静态变量默认存储在TLS

一、多线程共享变量

如果我们需要在多线程中使用全局变量、静态变量,就需要使用关键字shared

import std.stdio, core.thread;

shared x = 3;

void main()
{
    static shared y = 3;
    x = 5;
    y = 5;
    writeln("Main Thread: x=", x);
    writeln("Main Thread: y=", x);

    new Thread({ 
        writeln("Child Thread: x=", x); 
        writeln("Child Thread: y=", y);
    }).start();

    Thread.sleep(dur!("seconds")(2));
}

输出结果:

Main Thread: x=5
Main Thread: y=5
Child Thread: x=5
Child Thread: y=5

变量值相同了,所以证明了主线程和子线程共用一个副本。

而shared关键字不仅仅只是将数据放入全局中,而且还改变了变量类型

import std.stdio;

void foo(shared int[] x)
{
    writeln(x);
}

void main()
{
    int[] arr = [1,2,3];
    foo(arr);
}

编译上面的代码会得到一个错误:Error: function main.foo(shared(int[]) x) is not callable using argument types (int[])

正确类型应该是:shared int[]

二、暴力共享

所谓暴力共享就是回归到C/C++那种原始的全局变量,但它是不安全的,不能用在安全函数中,比如

import std.stdio;

void foo(shared int[] x) @safe
{
    writeln(x);
}

void main()
{
    __gshared arr = [1,2,3];
    foo(arr);
}

这样无法通过编译,会得到错误:Error: function main.foo(shared(int[]) x) is not callable using argument types (int[])

那为什么还需要它呢?因为在和C/C++交互时可能会派上用场。

三、不可变数据不在TLS中

另外,对于用immutable声明的变量来说,不会存储在TLS中,因为不可变的数据本身就是线程安全的,所以不会使用到TLS。

参考:

https://dlang.org/articles/migrate-to-shared.html

你可能感兴趣的:(D语言)