Generate sequential IDs for each instance of a struct

后端 未结 2 1930
一整个雨季
一整个雨季 2020-12-10 13:26

I\'m writing a system where I have a collection of Objects, and each Object has a unique integral ID. Here\'s how I would do it in C++:

<         


        
相关标签:
2条回答
  • 2020-12-10 13:46

    Atomic variables can live in statics, so you can use it relatively straightforwardly (the downside is that you have global state).

    Example code: (playground link)

    use std::{
        sync::atomic::{AtomicUsize, Ordering},
        thread,
    };
    
    static OBJECT_COUNTER: AtomicUsize = AtomicUsize::new(0);
    
    #[derive(Debug)]
    struct Object(usize);
    
    impl Object {
        fn new() -> Self {
            Object(OBJECT_COUNTER.fetch_add(1, Ordering::SeqCst))
        }
    }
    
    fn main() {
        let threads = (0..10)
            .map(|_| thread::spawn(|| Object::new()))
            .collect::<Vec<_>>();
    
        for t in threads {
            println!("{:?}", t.join().unwrap());
        }
    }
    
    0 讨论(0)
  • 2020-12-10 13:50

    nor are global mutable variables safe

    Your C++ example seems like it would have thread-safety issues, but I don't know enough C++ to be sure.

    However, only unsynchronized global mutable variables are trouble. If you don't care about cross-thread issues, you can use a thread-local:

    use std::cell::Cell;
    
    #[derive(Debug)]
    struct Monster {
        id: usize,
        health: u8,
    }
    
    thread_local!(static MONSTER_ID: Cell<usize> = Cell::new(0));
    
    impl Monster {
        fn new(health: u8) -> Monster {
            MONSTER_ID.with(|thread_id| {
                let id = thread_id.get();
                thread_id.set(id + 1);
                Monster { id, health }
            })
        }
    }
    
    fn main() {
        let gnome = Monster::new(41);
        let troll = Monster::new(42);
    
        println!("gnome {:?}", gnome);
        println!("troll {:?}", troll);
    }
    

    If you do want something that works better with multiple threads, check out bluss' answer, which shows how to use an atomic variable.

    0 讨论(0)
提交回复
热议问题