2016-08-02 24 views
-1

Ein Thread berechnet einige Daten, die etwa 1 GB RAM benötigt und ein anderer Thread liest nur diese Daten. Was ist der beste Weg dies zu implementieren?Was ist der beste Weg, um eine große schreibgeschützte Struktur zwischen zwei Threads zu teilen?

use std::thread; 
use std::time::Duration; 

fn main() { 

    let mut shared: i32 = 0; // will be changed to big structure 

    thread::spawn(move || { 
     loop { 
      shared += 1; 
      println!("write shared {}", shared); 
      thread::sleep(Duration::from_secs(2)); 
     } 
    }); 

    thread::spawn(move || { 
     loop { 
      thread::sleep(Duration::from_secs(1)); 
      println!("read shared = ???"); // <---------------- ???? 
     } 
    }); 

    thread::sleep(Duration::from_secs(4)); 
    println!("main"); 
} 

können Sie führen this code online (play.rust-lang.org)

Antwort

2

Der Code und Ihre Aussagen haben zusammen nicht wirklich Sinn machen. Zum Beispiel gibt es nichts, was verhindert, dass der zweite Thread beendet wird, bevor der erste Thread überhaupt eine Chance hat zu starten. Ja, ich sehe die Betten, aber Schlafen ist keine lebensfähige Nebenläufigkeit Lösung.

Für die Frage, wie gefragt, würde ich eine channel verwenden. Dies erlaubt es, einen Wert zu erzeugen fädeln und dann das Eigentum an diesen Wert auf einen anderen Thread:

use std::thread; 
use std::sync::mpsc; 

fn main() { 
    let (tx, rx) = mpsc::channel(); 

    let a = thread::spawn(move || { 
     let large_value = 1; 
     println!("write large_value {}", large_value); 
     tx.send(large_value).expect("Unable to send"); 
    }); 

    let b = thread::spawn(move || { 
     let large_value = rx.recv().expect("Unable to receive"); 
     println!("read shared = {}", large_value); 
    }); 

    a.join().expect("Unable to join a"); 
    b.join().expect("Unable to join b"); 

    println!("main"); 
} 

Für den Code wie dargestellt, gibt es wirklich keine anderen Optionen außer einem Mutex oder RwLock. Dies ermöglicht ein Thread den gemeinsamen Wert für eine Weile mutieren, dann der andere Thread es für eine Weile (je nach den Launen der OS-Scheduler) lesen kann:

use std::thread; 
use std::time::Duration; 
use std::sync::{Arc, Mutex}; 

fn main() { 
    let shared = Arc::new(Mutex::new(0)); 

    let shared_1 = shared.clone(); 
    thread::spawn(move || { 
     loop { 
      let mut shared = shared_1.lock().expect("Unable to lock"); 
      *shared += 1; 
      println!("write large_value {}", *shared); 
     } 
    }); 

    thread::spawn(move || { 
     loop { 
      let shared = shared.lock().expect("Unable to lock"); 
      println!("read shared = {}", *shared); 
     } 
    }); 

    thread::sleep(Duration::from_secs(1)); 
    println!("main"); 
} 

Nichts davon ist besonders einzigartig in Rust; Kanäle sind sehr beliebt in Go und Clojure und Mutexe gibt es schon seit sehr langer Zeit. Ich würde vorschlagen, einen der zahlreichen Anfängerführer im Internet für Multithreading und die darin enthaltenen Gefahren auszuprobieren.