2015-07-27 12 views
6

मेरे पास एक विशाल वेक्टर है जो मैं समानांतर में लोड/कार्य करने में सक्षम होना चाहता हूं, उदा। एक धागे में पहले सौ हजार सूचकांक लोड करें, अगले में एक और आगे। इस कोड का एक बहुत गर्म हिस्सा होने जा रहा है के रूप में, मैं अवधारणा असुरक्षित कोड के इस निम्नलिखित सबूत के साथ आए हैं वृत्तखण्ड और Mutexes बिना यह करने के लिए:समानांतर में प्रोसेसिंग वीसी: सुरक्षित तरीके से कैसे करें, या अस्थिर सुविधाओं का उपयोग किए बिना?

let mut data:Vec<u32> = vec![1u32, 2, 3]; 
let head = data.as_mut_ptr(); 
let mut guards = (0..3).map(|i| 
    unsafe { 
    let mut target = std::ptr::Unique::new(head.offset(i)); 
    let guard = spawn(move || { 
     std::ptr::write(target.get_mut(), 10 + i as u32); 
    }); 
    guard 
    }); 

क्या मैं यहाँ याद है कि कर सकते हैं इसे संभावित रूप से उड़ाओ?

यह #![feature(unique)] का उपयोग करता है, इसलिए मुझे यह नहीं पता कि स्थिर में इसका उपयोग कैसे किया जाए। क्या इस तरह की चीज स्थिर में करने का कोई तरीका है (कच्चे पॉइंटर्स और Arc और Mutex के ओवरहेड का उपयोग किए बिना आदर्श रूप से सुरक्षित रूप से?

इसके अलावा, documentation for Unique को देखते हुए, यह

कहते हैं यह भी संकेत मिलता है कि सूचक की दिग्दर्शन Unique संदर्भ के लिए एक अनूठा पथ के बिना संशोधित किया जा नहीं करना चाहिए

मैं स्पष्ट नहीं कर रहा हूँ क्या "अद्वितीय पथ" का अर्थ है।

+1

'Vec.split_at_mut (..) 'आपके लिए काम कर सकता है? – llogiq

+0

आप इसे पारस्परिक रूप से विभाजित कर सकते हैं लेकिन आप अभी भी कार्यकर्ता धागे में स्वामित्व को स्थानांतरित करने के तरीके से अटक गए हैं और फिर इसे वापस प्राप्त कर सकते हैं। मैं यह नहीं देखता कि कार्यकर्ता धागे कंप्यूटिंग करते समय सुरक्षित रूप से ऐसा कैसे करें, पैरेंट थ्रेड में आपके पास अभी भी मूल vec पर उत्परिवर्तनीय पहुंच है। जीवनकाल के मुद्दे भी हैं क्योंकि क्लोजर ब्लॉक से बच सकता है, अनबॉक्स किए गए बंद होने से यह ठीक हो सकता है - हालांकि मुझे उनके बारे में बहुत कुछ पता नहीं है। – sgldiv

+1

एक बार ['scoped'] (https://doc.rust-lang.org/nightly/std/thread/fn.scoped.html) उचित प्रतिस्थापन प्राप्त करता है 'split_at_mut' सही समाधान है। तब तक मैं सुझाव देता हूं कि प्रत्येक धागे के लिए एक से अधिक वैक्टर बनाएं। इस प्रयोजन के लिए –

उत्तर

5

कोई इसके लिए बाहरी पुस्तकालय का उपयोग कर सकता है, उदा।

extern crate simple_parallel; 

let mut data = vec![1u32, 2, 3, 4, 5]; 

let mut pool = simple_parallel::Pool::new(4); 

pool.for_(data.chunks_mut(3), |target| { 
    // do stuff with `target` 
}) 

chunks और chunks_mut तरीकों समान रूप से आकार टुकड़ों में T रों का एक वेक्टर/टुकड़ा विभाजित करने के लिए सही तरीका है: simple_parallel (त्याग, मैं इसे लिखा था) एक लिखने की अनुमति देता है कि वे क्रमश: तत्वों पर एक इटरेटर वापसी और &mut [T] टाइप करें।

+0

धन्यवाद! यह बहुत उपयोगी है। हालांकि मैं इसके बारे में सभी विवरणों को हल करना चाहता हूं, इसलिए मैं सीख सकता हूं। मैंने चैनलों का उपयोग करके ऐसा करने का विचार नहीं किया था। मुझे इसके बारे में कुछ और सोचने की आवश्यकता होगी। – sgldiv

+1

मैंने अपना खुद का https://github.com/rust-lang/threadpool के साथ घुमाया। http://huonw.github.io/blog/2015/05/finding-closure-in-rust/ बहुत उपयोगी था। – sgldiv

संबंधित मुद्दे

 संबंधित मुद्दे