【问题标题】:Share Barrier across threads in D在 D 中跨线程共享屏障
【发布时间】:2016-07-13 19:46:12
【问题描述】:

我花了很长时间试图让 D 中的屏障同步正常工作。我目前没有收到任何编译器错误,但是每次到达障碍时我都会遇到分段错误。这基本上是我所拥有的:

import std.stdio;
import std.conv;
import std.concurrency;
import core.thread;
import core.sync.barrier;

//create barrier
Barrier barrier;

void the_thread()
{
    barrier.wait(); //I get a segmentation fault here
}

void main(string[] args)
{
    int threads = to!int(args[1]); //number of threads

    //init barrier
    barrier = new Barrier(threads);

    //launch threads
    foreach(i; 0 .. threads)
    {
       spawn(&the_thread);
    }
    thread_joinAll();
}

我尝试在主函数中完全定义屏障,但 dmd 抱怨:

static assert  "Aliases to mutable thread-local data not allowed."

我也尝试将它作为共享变量传递,我得到了这个:

non-shared method core.sync.barrier.Barrier.wait is not callable using a shared object

【问题讨论】:

  • 将屏障标记为 __gshared 使其对我有用(在 Windows 上)。

标签: synchronization d dmd barrier


【解决方案1】:

全局变量在D中默认是线程局部的。当你在主线程中设置barrier时,你只在主线程中设置;对于其他线程,barrier 将是 null

您可以将barrier 标记为__gshared 以使其成为线程全局的,尽管这有点小技巧:

__gshared Barrier barrier;

正如您所发现的,线程生成函数只允许传递标记为shared 的数据。但是,由于Barrier.wait 函数未标记为shared,因此您不能使用shared(Barrier) 对象调用它,使其几乎无用。作为另一个 hack,您可以在调用 wait 之前先将其强制转换为非共享:

(cast()barrier).wait();

【讨论】:

  • 啊!我知道这将是我不理解的 D 中的内存管理。现在,您已将这两种方法都描述为 hack。这是在 D 中实现这种共享的方式,还是有一种非黑客的方式可以实现?
  • shared 有点……未指定。我的解释是,跨线程共享的任何数据都必须是shared,只有shared 方法可以在shared 对象上调用,并且只有在线程具有对对象的独占访问权限时才定义转换为非共享对象(例如。受互斥体保护)。所以Barrier.waitMutex.lock等函数应该是shared,但它们不是,这是IMO标准库中的一个不足。
  • @ColonelThirtyTwo 您应该为此在错误跟踪器中创建票证。
猜你喜欢
  • 2021-12-11
  • 1970-01-01
  • 1970-01-01
  • 2021-09-12
  • 1970-01-01
  • 1970-01-01
  • 2011-05-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多