Thread-safe mutable non-ownership pointer in Rust?

I am trying to parallelize the algorithm that I have. This is a sketch of how I will write it in C ++:

void thread_func(std::vector<int>& results, int threadid) {
   results[threadid] = threadid;
}

std::vector<int> foo() {
  std::vector<int> results(4);

  for(int i = 0; i < 4; i++)
  {
     spawn_thread(thread_func, results, i);
  }

  join_threads();

  return results;
}

The fact is that each thread has a link to a common, mutable object that it does not have. It seems like it's hard to do in Rust. Should I try to combine this in terms of (and I guess here) Mutex, Celland &mut, or is there a better pattern that I should follow?

+4
source share
1 answer

- Arc<Mutex<...>> , , Arc<RWLock<...>>. Arc - concurrency, , , Mutex/RWLock . :

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

fn thread_func(results: Arc<Mutex<Vec<i32>>>, thread_id: i32) {
    let mut results = results.lock().unwrap();
    results[thread_id as usize] = thread_id;
}

fn foo() -> Arc<Mutex<Vec<i32>>> {
    let results = Arc::new(Mutex::new(vec![0; 4]));

    let guards: Vec<_> = (0..4).map(|i| {
        let results = results.clone();
        thread::spawn(move || thread_func(results, i))
    }).collect();

    for guard in guards {
        guard.join();
    }

    results
}

, , Arc<Mutex<Vec<i32>>> , "" . .

, scoped_threadpool ( , - , , thread::scoped() , ), :

extern crate scoped_threadpool;

use scoped_threadpool::Pool;

fn thread_func(result: &mut i32, thread_id: i32) {
    *result = thread_id;
}

fn foo() -> Vec<i32> {
    let results = vec![0; 4];
    let mut pool = Pool::new(4);

    pool.scoped(|scope| {
        for (i, e) in results.iter_mut().enumerate() {
            scope.execute(move || thread_func(e, i as i32));
        }
    });

    results
}

thread_func , , Mutex, :

extern crate scoped_threadpool;

use std::sync::Mutex;

use scoped_threadpool::Pool;

fn thread_func(results: &Mutex<Vec<u32>>, thread_id: i32) {
    let mut results = results.lock().unwrap();
    result[thread_id as usize] = thread_id;
}

fn foo() -> Vec<i32> {
    let results = Mutex::new(vec![0; 4]);
    let mut pool = Pool::new(4);

    pool.scoped(|scope| {
        for i in 0..4 {
            scope.execute(move || thread_func(&results, i));
        }
    });

    results.lock().unwrap().clone()
}

Arc. execute() unsafe, , , . , 1.4.0, script.

+6

All Articles