Rust singleton pattern

hi,

how do I craete a global, mutable singleton object with only part of operations under lock?

Rust singleton object need to be wrapped in Mutex, which mean every operation need to be protected under lock guard. it's very inefficient sometimes,
e.g

lazy_static! {
    static ref ARRAY: Mutex<Vec<u8>> = Mutex::new(vec![]);
}

fn do_a_call() {
    ARRAY.lock().unwrap().push(1);
}

With C++, I can write code like this:

class A {
public:
	int a() { //no lock
		return 1;
	}
	void b() { //need lock
		static mutex lock;
		std::lock_guard<Mutex>guard(&lock);
		…
	}
}
A a;  //singleton object

But in rust, what's the best practice to do the same thing??

It's slightly unclear under what situation you want to not lock. Perhaps this?

use std::sync::Mutex;
use std::sync::atomic::{AtomicUsize, Ordering};

lazy_static! {
    static ref MY_GLOBAL: Global = Global {
        vec: Mutex::new(vec![]),
        num: AtomicUsize::new(0),
    };
}

struct Global {
    vec: Mutex<Vec<u8>>,
    num: AtomicUsize,
}

fn append(n: u8) {
    MY_GLOBAL.vec.lock().unwrap().push(n);
}
fn increment() -> usize {
    MY_GLOBAL.num.fetch_add(1, Ordering::Relaxed)
}
2 Likes

Thanks a lot for your reply, I wronly thought that global variable could not be access from multi-thread.