2017-12-14 13 views
1

Rust 프로그램의 모든 스레드에서 잠금없이 결과적으로 일관성있는 동시 다중 값 맵 evmap을 공유하고 싶습니다.`lazy_static` 내부에서`evmap`을 사용할 수 있습니까?

순진, 그 결과는 다음과 같습니다

#[macro_use] 
extern crate lazy_static; 

extern crate evmap; 

use std::collections::hash_map::RandomState; 

lazy_static! { 
    static ref MAP: (evmap::ReadHandle<u32, u32,(), RandomState>, 
        evmap::WriteHandle<u32, u32,(), RandomState>) = evmap::new(); 
} 

fn main() { 
    println!("Hello, world!"); 
    MAP.1.clear(); 
} 

이 제공 :

pub fn new<K, V>(
) -> (ReadHandle<K, V,(), RandomState>, WriteHandle<K, V,(), RandomState>) where 
    K: Eq + Hash + Clone, 
    V: Eq + ShallowCopy, 

을 수 :

error[E0277]: the trait bound `std::cell::Cell<()>: std::marker::Sync` is not satisfied in `(evmap::ReadHandle<u32, u32>, evmap::WriteHandle<u32, u32>)` 
    --> src/main.rs:8:1 
    | 
8 |/lazy_static! { 
9 | |  static ref MAP: (evmap::ReadHandle<u32, u32,(), RandomState>, 
10 | |      evmap::WriteHandle<u32, u32,(), RandomState>) = evmap::new(); 
11 | | } 
    | |_^ `std::cell::Cell<()>` cannot be shared between threads safely 
    | 
    = help: within `(evmap::ReadHandle<u32, u32>, evmap::WriteHandle<u32, u32>)`, the trait `std::marker::Sync` is not implemented for `std::cell::Cell<()>` 
    = note: required because it appears within the type `std::marker::PhantomData<std::cell::Cell<()>>` 
    = note: required because it appears within the type `evmap::ReadHandle<u32, u32>` 
    = note: required because it appears within the type `(evmap::ReadHandle<u32, u32>, evmap::WriteHandle<u32, u32>)` 
    = note: required by `lazy_static::lazy::Lazy` 
    = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) 

나는이 evmap::new() 내부 반환 ()에 대해 불평 생각 끝내라?

답변

1

[게으른 정적 변수에 직접 ReadHandle/WriteHandle 배치] 수 할 수?

아니오. 오류 메시지가 상태로 :

std::cell::Cell<()>는 스레드간에 공유 할 수 없습니다

안전하게

당신은 정적 변수에 다중 스레드 환경에서 사용할 때 실패 유형, 스레드가 있어야합니다 배치하려는

-안전한.

[게으른 정적 변수에 ReadHandle/WriteHandle 넣기] 할 수 있습니까?

,하지만 당신은 그런 Mutex 또는 RwLock으로 접근, 동기화 뭔가를 사용해야합니다 : 또한

#[macro_use] 
extern crate lazy_static; 

extern crate evmap; 

use std::collections::hash_map::RandomState; 
use std::sync::Mutex; 

type ReadHandle = evmap::ReadHandle<u32, u32,(), RandomState>; 
type WriteHandle = evmap::WriteHandle<u32, u32,(), RandomState>; 

lazy_static! { 
    static ref MAP: (Mutex<ReadHandle>, Mutex<WriteHandle>) = { 
     let (r, w) = evmap::new(); 
     (Mutex::new(r), Mutex::new(w)) 
    }; 
} 

fn main() { 
    MAP.1.lock().unwrap().clear(1); 
} 

참조 :

+0

안녕하세요 다시 Shepmaster! 감사. 잠금없는 데이터 구조와 같은 종류의 잠금을 사용하면이 점을 피할 수 있습니다. 내가 사용할 수있는 또 다른지도가 있다면 궁금합니다 ... –

+0

@EddBarrett 그건 까다로울 것입니다. lazy_static은 실제로 DerefMut을 구현하지 않으므로 변경할 수있는 메소드를 호출 할 수 없으므로 다른 메소드 인 "참조"링크를 추가하여 "강제"하는 방법을 "추가"했습니다. 'RefCell' 또는 비슷한 것을 필요로합니다. 라이브러리가 일반 변수로 사용하려는 것 같습니다. 그것이 중요하다면 관리자에게 물어볼 가치가 있습니다. – Shepmaster