简体   繁体   English

Rust lazy_static 变量 RwLock 访问

[英]Rust lazy_static variable RwLock access

I am trying to declare and read/write an instance of a custom struct, using lazy_static as I had to use non-const function at its initialization (string).我正在尝试使用lazy_static声明和读/写自定义结构的实例,因为我必须在其初始化(字符串)时使用非常量函数。

As I saw here in an other Stackoverflow post, I tried to use RwLock, which works fine when it comes to write, but fails when it comes to read, with the following error:当我看到这里在其他岗位#1,我试图用rwlock中,当谈到写这工作得很好,但是当涉及到阅读,并出现以下错误失败:

thread 'main' panicked at 'rwlock read lock would result in deadlock', /Users/adrien/.rustup/toolchains/stable-x86_64-apple-darwin/lib/rustlib/src/rust/library/std/src/sys/unix/rwlock.rs:47:13
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
pub struct Authentication {
    access_token: String,
    refresh_token: String,
    expiration: u32
}

lazy_static! {
    static ref LATEST_AUTH: RwLock<Authentication> = RwLock::new(Authentication {
        access_token: "access".to_string(),
        refresh_token: "refresh".to_string(),
        expiration: 0
    });
}

pub fn auth(){
   let api_resp: ApiResponse = res.json().unwrap(); //From a reqwest res
   let mut au = LATEST_AUTH.write().unwrap();
   au.access_token = api_resp.access_token.clone();
   println!("LATEST_AUTH:{}", LATEST_AUTH.read().unwrap()); //Fails
}

A RwLock is locked for the entire scope of the lock guard, which is obtained from calls to read() or write() .一个RwLock在整个锁保护范围内被锁定,它是通过调用read()write()

In your case, the write lock guard, au , lives for the entire duration of the auth function.在您的情况下,写锁保护auauth函数的整个持续时间内都存在。 This is what the error is saying: you've already locked it and then trying to lock it again in the same thread will make it block forever.这就是错误所说的:您已经锁定它,然后尝试在同一线程中再次锁定它会使其永远阻塞。

Write locks can also be used for reading, so you can fix this by just re-using that instead of trying to lock it again:写锁也可用于读取,因此您可以通过重新使用它而不是尝试再次锁定来解决此问题:

pub fn auth(){
   let api_resp: ApiResponse = res.json().unwrap();
   let mut au = LATEST_AUTH.write().unwrap();
   au.access_token = api_resp.access_token.clone();
   println!("LATEST_AUTH:{}", au);
}

Alternatively, you can force the lock to be dropped sooner, so that you can lock it for reading separately:或者,您可以强制更快地解除锁定,以便您可以锁定它以单独读取:

pub fn auth(){
   let api_resp: ApiResponse = res.json().unwrap();
   let mut au = LATEST_AUTH.write().unwrap();
   au.access_token = api_resp.access_token.clone();
   std::mem::drop(au);
   println!("LATEST_AUTH:{}", LATEST_AUTH.read().unwrap());
}

Or:或者:

pub fn auth(){
   let api_resp: ApiResponse = res.json().unwrap();
   // a new scope
   {
       let mut au = LATEST_AUTH.write().unwrap();
       au.access_token = api_resp.access_token.clone();
       // au will be dropped here, when it goes out of scope
   }
   println!("LATEST_AUTH:{}", LATEST_AUTH.read().unwrap());
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM