Rust lazy_静态变量RwLock访问

Rust lazy_静态变量RwLock访问,rust,static,rwlock,lazy-static,Rust,Static,Rwlock,Lazy Static,我正试图使用lazy\u static声明和读/写自定义结构的实例,因为我必须在初始化时使用非常量函数(字符串) 正如我在另一篇Stackoverflow文章中看到的,我尝试使用rBlock,它在写入时工作良好,但在读取时失败,错误如下: 线程“main”在“rwlock read lock将导致死锁”时惊慌失措,/Users/adrien/.rustup/toolschains/stable-x86_64-apple-darwin/lib/rustlib/src/rust/library/st

我正试图使用
lazy\u static
声明和读/写自定义结构的实例,因为我必须在初始化时使用非常量函数(字符串)

正如我在另一篇Stackoverflow文章中看到的,我尝试使用rBlock,它在写入时工作良好,但在读取时失败,错误如下:

线程“main”在“rwlock read lock将导致死锁”时惊慌失措,/Users/adrien/.rustup/toolschains/stable-x86_64-apple-darwin/lib/rustlib/src/rust/library/std/src/sys/unix/rwlock.rs:47:13
注意:使用'RUST_BACKTRACE=1'环境变量运行以显示回溯
pub结构验证{
访问令牌:字符串,
刷新令牌:字符串,
有效期:u32
}
懒惰的人!{
static ref LATEST_AUTH:RwLock=RwLock::new(身份验证{
访问令牌:“访问”。访问字符串(),
刷新\u标记:“刷新”。到\u字符串(),
有效期:0
});
}
发布fn auth(){
让api_resp:ApiResponse=res.json().unwrap();//从reqwest res
让mut au=LATEST_AUTH.write().unwrap();
au.access_token=api_resp.access_token.clone();
println!(“最新授权:{}”,最新授权读取().unwrap());//失败
}

A
RwLock
在锁保护的整个范围内被锁定,这是通过调用
read()
write()
获得的

在您的情况下,写锁保护,
au
,在整个
auth
函数期间都有效。这就是错误所说的:您已经锁定了它,然后尝试在同一线程中再次锁定它将使它永远阻塞

写锁也可用于读取,因此您可以通过重新使用而不是再次尝试锁定来修复此问题:

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);
}
或者,您可以强制更快地放下锁,以便可以单独锁定它进行读取:

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());
}
或:


RwLock
在锁保护的整个范围内都被锁定,这是通过调用
read()
write()
获得的

在您的情况下,写锁保护,
au
,在整个
auth
函数期间都有效。这就是错误所说的:您已经锁定了它,然后尝试在同一线程中再次锁定它将使它永远阻塞

写锁也可用于读取,因此您可以通过重新使用而不是再次尝试锁定来修复此问题:

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);
}
或者,您可以强制更快地放下锁,以便可以单独锁定它进行读取:

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());
}
或:


当您试图获取读锁时,您仍然持有写锁。你必须先放下写锁。写锁也允许读取,所以您实际上不需要它。谢谢,这样我就可以访问
au
。我只是好奇,但是我如何才能放下写锁?“持有”锁意味着范围内有一个锁防护装置。您需要先放下写锁以解锁它,然后才能再次锁定它进行读取。在您的情况下,
au
在整个
auth
函数中都有效,这意味着您也无法将其锁定进行读取。然而,正如麦卡顿所说,你可以从写锁中读取,最简单的修复方法是使用
au
进行读取,而不是获取新的读取锁。另一种修复方法是手动删除
au
,例如,使用
std::mem::drop(au)。当您试图获取读锁时,您仍然持有写锁。你必须先放下写锁。写锁也允许读取,所以您实际上不需要它。谢谢,这样我就可以访问
au
。我只是好奇,但是我如何才能放下写锁?“持有”锁意味着范围内有一个锁防护装置。您需要先放下写锁以解锁它,然后才能再次锁定它进行读取。在您的情况下,
au
在整个
auth
函数中都有效,这意味着您也无法将其锁定进行读取。然而,正如麦卡顿所说,你可以从写锁中读取,最简单的修复方法是使用
au
进行读取,而不是获取新的读取锁。另一种修复方法是手动删除
au
,例如,使用
std::mem::drop(au)