You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

101 lines
2.8 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

# 全局变量
在一些场景我们可能需要全局变量来简化状态共享的代码包括全局ID全局数据存储等等下面我们来一一给出对应的实现方法。
## 全局唯一ID
```rust
use std::sync::atomic::{Ordering, AtomicUsize};
struct Factory{
factory_id: usize,
}
static GLOBAL_ID_COUNTER: AtomicUsize = AtomicUsize::new(0);
// This gives large room for ids to overflow
// This code assumes that your app never would need many factories
const MAX_ID: usize = usize::MAX / 2;
fn generate_id()->usize{
// Check overflow twice to avoid growing of GLOBAL_ID_COUNTER after overflow.
let current_val = GLOBAL_ID_COUNTER.load(Ordering::Relaxed);
if current_val > MAX_ID{
panic!("Factory ids overflowed");
}
let next_id = GLOBAL_ID_COUNTER.fetch_add(1, Ordering::Relaxed);
if next_id > MAX_ID{
panic!("Factory ids overflowed");
}
next_id
}
impl Factory{
fn new()->Self{
Self{
factory_id: generate_id()
}
}
}
```
## 从函数中返回全局变量
https://www.reddit.com/r/learnrust/comments/rqn74g/cant_a_function_return_a_reference_to_some_global/
## lazy_static
```rust
use std::{sync::{Mutex, MutexGuard}, thread};
use std::thread::sleep;
use std::time::Duration;
use lazy_static::lazy_static;
lazy_static! {
static ref MUTEX1: Mutex<i64> = Mutex::new(0);
static ref MUTEX2: Mutex<i64> = Mutex::new(0);
}
fn main() {
// Spawn thread and store handles
let mut children = vec![];
for i_thread in 0..2 {
children.push(thread::spawn(move || {
for _ in 0..1 {
// Thread 1
if i_thread % 2 == 0 {
// Lock mutex1
// No need to specify type but yes create a dummy variable to prevent rust
// compiler from being lazy
let _guard: MutexGuard<i64> = MUTEX1.lock().unwrap();
// Just log
println!("Thread {} locked mutex1 and will try to lock the mutex2, after a nap !", i_thread);
// Here I sleep to let Thread 2 lock mutex2
sleep(Duration::from_millis(10));
// Lock mutex 2
let _guard = MUTEX2.lock().unwrap();
// Thread 2
} else {
// Lock mutex 1
let _guard = MUTEX2.lock().unwrap();
println!("Thread {} locked mutex2 and will try to lock the mutex1", i_thread);
// Here I freeze !
let _guard = MUTEX1.lock().unwrap();
}
}
}));
}
// Wait
for child in children {
let _ = child.join();
}
println!("This is not printed");
}
```
## box::leak