2013-07-26 6 views
6

È possibile condividere una variabile mutabile tra più thread in Rust? Dati i seguenti:Condivisione di variabili mutabili tra i thread in Rust

fn main() { 

    let mut msg = "Hi"; 
    // ... 
    msg = "Hello, World!"; 

    do spawn { 
     println(msg); 
    } 

    do spawn { 
     println(msg); 
    } 

} 

ottengo questo errore:

error

La variabile ha solo bisogno di essere in sola lettura ai fili deposto le uova. La variabile deve essere mutevole, perché quello che sto cercando di fare è condividere una HashMap tra più thread. Per quanto ne so non c'è modo di popolare una HashMap a meno che non sia mutabile. Anche se c'è un modo per farlo, sono comunque interessato a sapere come realizzare qualcosa di simile in generale.

Grazie!

risposta

8

Questa restrizione deve essere rimossa in una versione futura della lingua. Detto questo, puoi risolvere questo problema con let msg = msg; prima del primo do spawn. Questo sarà spostare il valore msg in una posizione immutabile, cambiando effettivamente la sua mutabilità.

+0

Questo ha fatto il trucco! Grazie! –

+1

Quando si dice "questa restrizione deve essere rimossa", cosa sta cambiando esattamente? Copia su cattura diventerà il valore predefinito? Oppure, sarai in grado di catturare una variabile mutabile fintanto che il tuo lambda viene creato dopo l'ultimo incarico ad esso? –

3

In caso di condivisione della stringa "Hello, World!", È sufficiente spostare la variabile in una posizione immutabile (ad es. "Let mut msg = .....; let msg = msg ; ").

Probabilmente vuoi anche evitare di creare una copia separata dell'hashmap per ogni thread che lo sta ricevendo, tuttavia, nel qual caso ti consigliamo di inserirlo anche in un ARC (wrapper conteggio di riferimento atomico), che tu " lo troverò in extra::arc.

+0

Quindi, quando si fa 'let msg = msg;' Rust sta facendo una copia immutabile di 'msg' per ogni thread generato? –

+0

@EvanByrne in quel caso Rust ombreggia un precedente riferimento mutabile con un nuovo riferimento immutabile. Questo riferimento immutabile può quindi essere passato ai thread. Almeno questo è il modo in cui capisco questo comportamento. –

3

La risposta "in generale" (relativa al mantenimento di una tabella hash mutabile mentre è condivisa) è che non è direttamente possibile; Rust è stato specificamente progettato per proibire la condivisione dello stato mutabile al fine di evitare determinati tipi di bug e per proteggere alcuni tipi di sicurezza (e per altri motivi).

Tuttavia, è possibile creare qualcosa di simile a una tabella hash mutabile condivisa. Immagina che una singola attività abbia una tabella hash mutabile. È possibile scrivere il codice in modo che altre attività possano inviarlo messaggi dicendo, in sostanza "Aggiornare la tabella hash in modo che 5 mappe a 18" o "Dimmi cosa 7 mappe a".

Cosa compie questa operazione indiretta? Innanzitutto, copiando i valori nei messaggi, non è possibile per un'altra attività calpestare tutta la memoria che sei nel mezzo della lettura (un grosso problema di sicurezza), e in secondo luogo, scrivendo il codice indirettamente, è più chiaro per il programmatore cos'è e non è un'operazione atomica; il programmatore saprà non aspettarsi che due messaggi consecutivi sui contenuti della tabella hash non riguardino necessariamente la stessa versione della tabella hash, un'ipotesi che è perfettamente valida (almeno in Rust, grazie ad alcune altre restrizioni) su due letture consecutive da una tabella hash non condivisa, mutevole.

+0

Sembra certamente un approccio promettente. C'è qualcosa di specifico nella libreria standard che potrebbe aiutarmi a realizzare una cosa del genere? –

+0

Non che io sappia, mi dispiace!La libreria standard è ancora in crescita; potresti voler considerare di aggiungerlo tu stesso. –

+0

Se trovo un modo per farlo, lo renderò disponibile su github :) –