2016-03-26 16 views
3

Dのバリア同期を正しく実行しようとしている時があります。私は現在、コンパイルエラーは発生していませんが、障壁に達するたびにセグメンテーション違反が発生します。ここで私が持っているものは基本的です: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." 

私も共有変数とIとしてそれを渡して試してみましたこれを取得する:あなたがあなたのメインスレッドでbarrierを設定し、あなただけのメインスレッドでそれを設定すると

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

__gshared'が、それは(Windows上で)私のために働く可能 'などのバリアをマーク。 – sigod

答えて

2

グローバル変数はD.デフォルトでスレッドローカルです。他のスレッドの場合、barriernullになります。それはハックのビットですけれども

あなたは、それがスレッドグローバル作るために__gsharedとしてbarrierをマークすることができます。

__gshared Barrier barrier; 

をスレッドスポーン機能は、あなたが発見したとして渡すデータは、sharedとしてマークできます。ただし、Barrier.wait関数はsharedとマークされていないため、shared(Barrier)オブジェクトで呼び出すことはできず、ほとんど役に立たなくなります。別のハックとして、あなたはwaitを呼び出す前に、非共有最初にキャストすることができます

(cast()barrier).wait(); 
+0

ああ!私はそれが私が理解していないDのメモリ管理の何かであることを知っていました。さて、これらの両方をハックとして説明しました。このような共有がDで成し遂げられるか、これを達成するための非ハッキリな方法がありますか? – jdeters

+0

'shared'は少しです... underspecified。私の解釈は、スレッド間で共有されるデータはすべて 'shared'する必要があり、' shared'メソッドだけが 'shared'オブジェクトで呼び出すことができ、unsharedへのキャストはスレッドがオブジェクトへの排他的アクセスを持つ場合にのみ定義されます。 mutexで保護されています)。したがって、 'Barrier.wait'、' Mutex.lock'などの関数は 'shared'でなければなりませんが、そうではありません.IMOは標準ライブラリの欠点です。 –

+0

@ColonelThirtyTwoバグトラッカーでチケットを作成する必要があります。 – sigod