2016-03-26 21 views
3

Ich habe eine Menge Zeit mit dem Versuch, die Barrieresynchronisation in D richtig zu funktionieren. Ich erhalte derzeit keine Compilerfehler, aber jedes Mal, wenn die Barriere erreicht wird, erhalte ich einen Segmentierungsfehler. Hier ist im Grunde, was ich habe:Share Barrier über Threads in 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(); 
} 

Ich habe versucht, die Definition der Barriere vollständig in der Hauptfunktion, aber DMD klagt:

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

Ich habe auch versucht, es als eine gemeinsame Variable vorbei und ich erhalten diese:

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

Kennzeichnung Barriere als '__gshared' es für mich macht Arbeit (unter Windows). – sigod

Antwort

2

globale Variablen lokalen thread~~POS=TRUNC in D. standardmäßig sind, wenn Sie barrier in Ihrem Haupt-Thread gesetzt, können Sie es nur im Hauptthread gesetzt; für die anderen Threads wird barriernull sein.

Sie können barrier als __gshared zu markieren, um es globalen Thread, obwohl es ein bisschen wie ein Hack ist:

__gshared Barrier barrier; 

Die Funktion Thread laichen erlaubt nur Daten markiert als shared vorbei, wie Sie entdeckt haben. Da die Barrier.wait-Funktion jedoch nicht als shared markiert ist, können Sie sie nicht mit einem shared(Barrier)-Objekt aufrufen, was sie größtenteils unbrauchbar macht. Als weiteres Hack, können Sie es zu unshared zuerst werfen, bevor wait Aufruf:

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

Ah! Ich wusste, dass es etwas mit Speicherverwaltung in D geben würde, das ich nicht verstand. Nun haben Sie beide als Hacks beschrieben. Wird diese Art des Teilens in D erreicht oder gibt es einen nicht-hakischen Weg, mit dem ich dies erreichen kann? – jdeters

+0

'shared' ist ein bisschen ... unterspezifiziert. Meine Interpretation ist, dass alle Daten, die über Threads geteilt werden, "shared" sein müssen, nur 'shared' Methoden können für' shared' Objekte aufgerufen werden, und Casting auf nicht-shared wird nur definiert, wenn der Thread exklusiven Zugriff auf ein Objekt hat (z. geschützt durch einen Mutex). So sollten Funktionen wie "Barrier.wait", "Mutex.lock" usw. "geteilt" werden, aber das sind sie nicht, was IMO ein Mangel in der Standardbibliothek ist. –

+0

@ColonThirtyTwo Sie sollten Ticket in Bug-Tracker dafür erstellen. – sigod