[[!tag learning-rust]]

  • I'm excited about this. Mainstream CPUs have been gaining more cores or hyperthreads since the early 2000s, but none of my programming languages have been particularly good at making use of those. C is just too complicated, and Python has the global interpreter lock, which ruins concurrency a lot. Python's getting better, but not well enough. Concurrency was one of the reasons I wanted to learn Haskell in 2003, but being a bear with a very small brain, I still haven't learnt much Haskell.

    Rust promises to make use of threads be much safer than using them in C, and that would be a really good thing.

  • This chapter also introduces networking, which also is exciting. Much of what I've done in recent years has been web API implementations, and I am looking forward to doing that in Rust.

  • New thing: std::cell::Cell with methods new, get, and put.

  • New thing: std::cell::RefCell with methods new, borrow, and borrow_mut. Borrow rules apply, but are checked runtime. Mutable borrows should be used sparingly.

  • New thing: std::rc::Rc — essentially a reference counted Box. Each Rc (clone of the original one) has an immutable reference to a heap value, and together they manage the reference count. When the count goes to zero, the heap value is freed. This is a bit like manual memory management, but piggy-backing Rust's normal memory management. Allows safe-ish data sharing for when the normal Rust rules get too much in the way. Involves some runtime overhead.

  • New thing: std::thread, especially spawn. A thread executes a closure. Threads are objects like others, e.g., they can be kept in vector to be joined.

  • Important point: threads need to move values, not borrow. If they borrow, the reference to the value they have may outlive the value in the original thread, which would be a bug. Values with 'static lifetimes can be borrowed across threads. Rc is not thread safe and can't be used to share references across threads. std::sync::Arc is a thread-safe version, with more runtime overhead.

    This seems fundamental for making threaded code safe: tightly controlled sharing of data and compile-time checks for violations of such sharing.

  • New thing: channels for inter-thread communication. A multiple-producer, single-consumer solution. There's a variant for synchronous channels, where senders block until their message has been received.

  • New thing: barriers for inter-thread synchronisation: all threads wait for all threads to reach the barriers, and then all threads continue. Presumably the barrier keeps track of how many threads have references to it, and how many are currently waiting for the barrier. This seems like a nice, easy synchronisation approach, which may still take some time to get used to.

  • New thing: mutexes. For protecting a shared resource from concurrent use. Note that this is different from barriers as it's about allowing only one thread to access the resource at a time. While the Rust mutex abstraction seems easier to use correctly than the corresponding C stuff, it's still not super-easy to be safe.

    Rust seems to provide, in the stdlib or as third-party crates, higher level abstractions that make concurrency easier to use safely. This is very good.

  • I don't understand from the GITR description what to_socket_addrs does for numeric addresses. Creates a socket that connects to the remote server+port? If not, how does the example check for addresses that are reachable hosts? What does :0 mean for port addresses?

  • Overall, Rust seems to model networking based on traditional networking concepts. Seems straightforward enough.