在Rust中的线程之间共享无锁资源

时间:2016-09-26 13:18:54

标签: multithreading rust

我在Rust中移植我的C ++国际象棋引擎。我有一个在搜索线程之间共享的大哈希表,在C ++版本中这个表是无锁的;没有用于共享读/写访问的互斥锁。如果您有兴趣,请参阅the theory

在此代码的Rust版本中,它工作正常,但使用Mutex

let shared_hash = Arc::new(Mutex::new(new_hash()));

for _ in 0..n_cpu {
    println!("start thread");
    let my_hash = shared_hash.clone();
    thread_pool.push(thread::spawn(move || {
        let mut my_hash = my_hash.lock().unwrap();
        let mut search_engine = SearchEngine::new();
        search_engine.search(&mut myhash);
    }));
}

for i in thread_pool {
    let _ = i.join();
}

如何在没有互斥锁的线程之间共享表?

3 个答案:

答案 0 :(得分:4)

非常简单,实际上:如果底层结构已经Mutex,则Sync是不必要的。

在你的情况下,例如原子结构的数组就可以了。你可以找到Rust的可用原子here

答案 1 :(得分:0)

C ++和Rust中的

Data races are undefined behavior。只是说不。

正确的方法是从atomic integers构建你的桌子。它是火箭科学。 You have to decide case by casecare about the order of memory operations多少钱。这会使代码混乱:

// non-atomic array access
table[h] = 0;

// atomic array access
table[h].store(0, Ordering::SeqCst);

但它值得。

不知道性能损失是什么 - 你只需要尝试一下。

答案 2 :(得分:-1)

正如所建议的那样,我编写了KEYUP来实现FakeMutex,但并没有真正锁定哈希表:

Sync

我的新代码是:

use core::cell::UnsafeCell;
use core::marker::Sync;
use core::ops::{Deref, DerefMut};

pub struct FakeMutex<T> {
    data: UnsafeCell<T>,
}

pub struct FakeMutexGuard<'a, T: 'a> {
    data: &'a mut T,
}

unsafe impl<T> Sync for FakeMutex<T> {}

impl<T> FakeMutex<T> {
    pub fn new(user_data: T) -> FakeMutex<T> {
        FakeMutex {
            data: UnsafeCell::new(user_data),
        }
    }

    pub fn lock(&self) -> FakeMutexGuard<T> {
        FakeMutexGuard {
            data: unsafe { &mut *self.data.get() },
        }
    }
}

impl<'a, T> Deref for FakeMutexGuard<'a, T>{
    type Target = T;
    fn deref<'b>(&'b self) -> &'b T { &*self.data }
}

impl<'a, T> DerefMut for FakeMutexGuard<'a, T>{
    fn deref_mut<'b>(&'b mut self) -> &'b mut T { &mut *self.data }
}

这解决了我的问题。