Rust

Rust - Borrowing mutable references

Previously published This article was previously published on len-learns-rust.com. A full index of these articles can be found here. In addition to managing the lifetimes of references to variables, the Rust compiler’s borrow checker also deals with enforcing Rust’s guarantees about mutability and so helps to prevent data races. Basically, you can have any number of immutable references to a variable, but only if there are no mutable references to it at the same time, and you can only ever have a single mutable reference.

Rust - Lifetimes

Previously published This article was previously published on len-learns-rust.com. A full index of these articles can be found here. One of the jobs of the Rust compiler’s “borrow checker” is to track the life of each reference to a variable so that it can prevent dangling references. To do this, it annotates each variable and reference with details of the scope in which it is valid. This annotation is called a lifetime.

Rust - Deadlocks

Previously published This article was previously published on len-learns-rust.com. A full index of these articles can be found here. One reason that access shared data using locks is a bad idea is that, in complex code, it may be possible to deadlock. At their simplest, deadlocks are caused when one thread (thread a) obtains and holds a lock which another thread (thread b) requires whilst itself being blocked from obtaining a lock that it requires because thread b already holds it… Unfortunately, whilst Rust has eliminated data races in multithreaded code, it doesn’t prevent the possibility of deadlocks.

Rust - Accessing the Id Manager from multiple threads

Previously published This article was previously published on len-learns-rust.com. A full index of these articles can be found here. Since I now understand a little about how to share data between threads I can try and use my Id Manager from multiple threads. Following the same pattern as I’ve been using with the other threading code, something like this might work… #[test] fn test_channel_thread_with_id_manager() { let id_manager = Arc::new(IdManager::<u8>::new(ReuseSlow)); let shared_manager = Arc::clone(&id_manager); let data = Arc::new(Mutex::new(HashMap::<String, Id<u8>>::new())); let shared_data = Arc::clone(&data); let mut thread = ChannelThread::new(move |message| { let id = shared_manager.

Rust - Sharing data between threads

Previously published This article was previously published on len-learns-rust.com. A full index of these articles can be found here. Now that we can send messages to threads I want to see how we can access shared data from those threads. This isn’t the best design choice as shared data needs to be protected by locks so that it is accessed in an atomic fashion and the various threads involved with this data will contend with each other over the locks.

Rust - Simple threading

Previously published This article was previously published on len-learns-rust.com. A full index of these articles can be found here. The simplest threading is already covered by most Rust books. Starting up a thread, passing stuff to it, letting it run and waiting for it to finish. Something like this is the basic thread example in Rust. This work’s and is easy to understand and reason about. The spawned thread clearly runs for less time than the main thread as we join with it before the main thread completes but we rely on the spawned thread to decide when to shut down, this isn’t that important here as the spawned thread has a finite amount of work to do, but for threads that do a potentially infinite amount of work I will need a way to ask the thread to stop…

Rust - Thinking about threading

Previously published This article was previously published on len-learns-rust.com. A full index of these articles can be found here. My threading background in C++ on Windows and Linux goes back a long way and that means that I have some set ways of doing things that may not map directly to the Rust way of doing things. I tend to use threads with the following patterns at present: A thread starts up, waits on one or more externally controlled ’events’ and, when one of these is triggered the thread does something, or shuts down.

Rust - Threading

Previously published This article was previously published on len-learns-rust.com. A full index of these articles can be found here. Now that I have my generic IdManager I’d like to use it from multiple threads. As I said, this code would normally be used for things like connection ids for network protocols and I’ve spent the past 20 years or so writing servers that use small numbers of threads to handle many thousands of connections with work for each connection being given to a thread from a thread pool to perform.

Rust - The journey so far

Previously published This article was previously published on len-learns-rust.com. A full index of these articles can be found here. I’ve now built a generic IdManager which does everything I want it to do, for now. I’ve bumbled along in a very non-scientific manner, mostly using the compiler errors to guide me towards things I’ve then looked up on the web. The code works and is tested, but it’s now time to go back to the books with a series of questions that this journey has got me thinking about:

Rust - Clean up and additional functionality

Previously published This article was previously published on len-learns-rust.com. A full index of these articles can be found here. We now have a generic IdManager so now we just need to finish off the required functionality. The missing pieces are: a “reuse policy”, so we can dictate how new ids are allocated the ability to restrict the range of ids used. the ability to mark some ids as used The first of these is to allow us to use the id range “in order” before we start using ids that have been returned to us.