2015-03-08 13 views
6

Birisi aşağıdaki kodun neden paralel olarak çalışmadığını açıklayabilir mi? Ben thread::scoped eser ..İş parçacığı kullanırken paralel olarak çalışmayan kod :: scoped

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

fn main() { 
    let buf = Arc::new(Mutex::new(Vec::<String>::new())); 
    let res = test(buf); 
    println!("{:?}", *res.lock().unwrap()); 
} 

fn test(buf: Arc<Mutex<Vec<String>>>) -> Arc<Mutex<Vec<String>>> { 
    let guards: Vec<_> = (0..3).map(|i| { 
     let mtx = buf.clone(); 
     thread::scoped(|| { 
      println!("Thread: {}", i); 
      let mut res = mtx.lock().unwrap(); 
      timer::sleep(Duration::seconds(5)); 
      res.push(format!("thread {}", i)); 
     }); 
    }).collect(); 
    buf 
} 

kod dile getirilmiştir örnekler here dayanmaktadır anlamıyorum galiba:

kapsamlı fonksiyon ile gösterilen bir argüman, bir kapatma alır çift ​​çubuklar. Bu kapatma, scoped tarafından oluşturulan yeni bir iş parçacığında yürütülür. Yöntem, kapsam dışına çıktığında otomatik olarak çocuk iş parçacığına katılacak olan bir 'birleştirme bekçisi' döndürdüğü için kapsamlıdır. Bu muhafızları bir Vec olarak topladığımızdan ve programımızın sonunda vektörün kapsam dışı kalmasından dolayı, programımız her iş parçacığının bitirmeden önce bitmesini bekleyecektir.

Teşekkür

+2

[PR] (https://github.com/rust-lang/rust/pull/23202) orijinal belgeler düzeltmek için. – Shepmaster

cevap

10

Bu zor bir durumdur. Sorun, mütevazı noktalı virgül. Bu minimize koduna bak:

thread::scoped(|| {}); 

O noktalı virgül collectsonucu değil JoinGuard s'lik bir vektör anlamına gelir - bir Vec<()> var! Her bir JoinGuard hemen bırakılır ve sonraki iterasyon başlamadan önce iş parçacığının bitmesine zorlanır.

Bu sorunu giderdiğinizde, bir sonraki soruna da varacaksınız; bu, i ve mtx yeterince uzun süre yaşamaz. Sen kapatılması halinde bunları move gerekir: Gönderdiğim

thread::scoped(move || {}) 
+1

Bunun gibi görünüyor "JoinGuard", # [must_use] 'mabye için bir aday mı? – sellibitze

+0

@sellibitze kesinlikle iyi bir olasılık olabilirmiş gibi görünüyor! Bunun için doğru süreç nedir? – Shepmaster

+0

"# pas-internals" içindeki çekirdek devrelere atmayı deneyin ve ne olduğunu görün, sanırım. :) – sellibitze

İlgili konular