[HN Gopher] Shared mutable state in Rust (2022)
       ___________________________________________________________________
        
       Shared mutable state in Rust (2022)
        
       Author : vinhnx
       Score  : 39 points
       Date   : 2026-04-01 23:33 UTC (3 days ago)
        
 (HTM) web link (draft.ryhl.io)
 (TXT) w3m dump (draft.ryhl.io)
        
       | FpUser wrote:
       | I have shared mutable state which is available through the whole
       | application lifetime. Having ARC in this situation makes no
       | sense, single mutex should be all I need.
        
         | LtdJorge wrote:
         | Use a LazyLock for your state, then
        
         | kd5bjo wrote:
         | That's also an option available to you: Mutex::new() is const,
         | so there's no trouble putting one in a static variable. If the
         | inner value can't be const-constructed, you'll need a way to
         | prevent access before it's initialized; for that, you can use a
         | OnceLock or just Box::leak() the Mutex once it's constructed
         | and pass around a simple reference.
        
           | Ciantic wrote:
           | I happen to be just now experimenting with app states. Out of
           | interest, you mean something like this? https://gist.github.c
           | om/Ciantic/63526ebfe65570b669eca33bf340...
           | 
           | What would be disadvanatages of this approach? I don't like
           | Arc's myself either, I would like to see what is best
           | alternative for those in multi threaded apps.
        
             | maxbond wrote:
             | Different commenter but yes, that's exactly what they mean.
             | 
             | The main disadvantage is strong coupling. The shared state
             | inside the static makes it more difficult to test your
             | code. There are ways to reduce this coupling, the most
             | obvious being that you push as much logic as possible into
             | functions that accept a reference rather than use your
             | static directly. Then you minimize the size of the code
             | which is difficult to test, and cover it with end to end
             | testing.
             | 
             | The OnceLock does impose 1 atomic operation of overhead,
             | whereas an Arc imposes 2 (in this case, it can be more if
             | weak references are used). However neither are likely to be
             | important when you consider the overhead of the Mutex; the
             | Mutex is likely to involve system calls and so will
             | dominate the overhead. (If there's little to no contention
             | then the Mutex is a lot like an Arc.)
             | 
             | Your alternative would be to use `Box::leak()` as the
             | parent comment describes, which would force you to pass a
             | reference around (resulting in better coupling) and
             | eliminate overhead from OnceLock. However, it's unlikely to
             | result in any material performance benefit, and you could
             | reduce coupling without departing from your current
             | approach, so I don't think either approach is clearly or
             | overwhelmingly better.
        
         | mplanchard wrote:
         | You can Box::leak() it to make a &'static ref to it.
        
       | the__alchemist wrote:
       | I think which tools you use for concurrency depends on your code
       | style and what you're doing. For example, I haven't reached for
       | Arc in a while. Example of the two primary ways I've been doing
       | it:
       | 
       | Embedded: Mutex + critical sections + hardware interrupts. The
       | Mutex isn't std::Mutex, but a hardware-specific one. (E.g. ARM)
       | works in a similar way. The default syntax is a mess of RefCell,
       | Cell, Option, with the requisite < and > characters. (The Option
       | is so you can insert a value in on init, then it's never None)
       | etc. I work around this with macros.
       | 
       | PC applications (GUI, 3D etc): std::thread and MPSC
       | receivers/transmitters which update a state struct when they're
       | ready. Then poll in the GUI's event loop or w/e. I believe this
       | workflow has worked for me in lieu of Arc because I have been
       | structuring programs with a single main thread, then sub threads
       | which perform non-blocking tasks, then return data to the main
       | thread.
       | 
       | Also: If it's a primitive type, Atomics are nice.
        
       ___________________________________________________________________
       (page generated 2026-04-05 23:01 UTC)