2013-03-09 6 views
6

So che Rust può eseguire cicli con fili leggeri. Qualcosa di simile:multithreading in D con ciclo for

use task::spawn; 

fn main() { 
    for 100.times { 
    do spawn { 
     io::println("Hello"); 
    } 
    } 

Come posso farlo in D?

risposta

11

Rilevante API doc: std.parallelism

Qui ci sono alcuni dei modi di realizzare il tuo esempio:

foreach parallelo, utilizzando un TaskPool parallel:

foreach (i, val; taskPool.parallel(new int[50])) { 
    writeln("Hello:", i); 
} 

foreach regolare, aggiungendo attività a un pool di attività utilizzando put:

foreach (i; 0 .. 50) { 
    auto t = task!writeln("Hello:", i); 
    taskPool.put(t); 
} 

Esegui ogni attività in un new thread invece di un TaskPool: runtime

foreach (i; 0 .. 50) { 
    auto t = task!writeln("Hello:", i); 
    t.executeInNewThread(); 
} 

di Rust ha un programmatore di operazione built-in, ma con D, questo è implementato come una biblioteca. Detto questo, il secondo è il più vicino in termini di funzionalità, e l'ultimo è il più vicino in termini di sintassi (ma sono thread del sistema operativo, non leggeri).

In D, i thread leggeri sono esplicitamente controllati dal programmatore. Un TaskPool è analogo allo scheduler in Rust/Go, ma fornisce un controllo più dettagliato al programmatore. Ciò lo rende leggermente più prolisso, ma fornisce anche versioni parallele di map, reduce, foreach, ecc. Ciò rende più semplice rappresentare algoritmi più complessi in modo efficiente.

L'esecuzione di ogni esempio dovrebbe fornire il risultato previsto: scritture non funzionanti.

Nota:

Dal doc:

I thread di lavoro in questa piscina sono thread demoni, il che significa che non è necessario chiamare o TaskPool.stop TaskPool.finish prima di terminare la filo principale.

Il secondo esempio non attende fino a quando tutti i lavoratori sono terminati, quindi durante i test non si ottengono risultati (al termine delle operazioni principali, tutte le attività rimanenti vengono eliminate). Potrebbe essere necessario bloccare chiamando finish:

taskPool.finish(true); 
+0

Posso fare qualcosa di simile: for (int i = 0; i <10; i.parallel) { WRI teln ("elaborazione", i); } ? – Suliman

+0

@ Suliman - È una domanda sulla sintassi? Perché è quasi esattamente ciò che fanno i primi due (il secondo in più). Devi usare l'oggetto taskPool anche se D non lo farà per te. – tjameson

+0

Sì, sulla sintassi. – Suliman

8

D non ci sono astrazioni incorporate per fili leggeri.Invece, è possibile:

  • uso fili (vedi std.concurrency e std.parallelism)
  • uso fibers, e multitasking manualmente esplicitamente cedendo esecuzione
  • utilizzare una libreria come Vibe.d, che implementa I/O asincrono utilizzando fibre e implicita cedendo sulle operazioni di blocco