Is there a multi-thread version of std::cell::RefCell?

I know of std::sync::{Mutex, RwLock}, however these types don't implement Clone. I found working with them a bit discomfortable. I used them in my project rialight::intl::ftl.

Is there something more handy?

P.S.: links

If you need to clone a Mutex or RwLock you normally wrap them in an Arc.


That could be an option, but... for a node containing many properties, that could be memory-inefficient, I guess (due to heap allocations)?

You should probably not put every individual field behind a separate Arc<Mutex>; that usually indicates you think you are doing something atomically when in fact your code is actually racy.

If you think every copy of an Arc allocates: that's not the case – if it worked like that, it would have no point (it would be the same as Box). All copies of an Arc point to the same allocation, that's what reference counting is.

It happens that I need to mutate the fields in their type's instance methods. I know I can borrow the type as mutable (&mut self), but I recall that puts some limitations on the type usage.

Have you verified that heap allocating your Mutex-wrapped value is the performance bottleneck in your application? If not then this smells like premature optimization to me. Depending on your program you could spend way more time syncing on your Mutex than you spend on accessing your heap.

1 Like

I know. What I wanted to mean is that I don't want every field to be heap-allocated.

I do think it may be critical for a display list node hierarchy to store all fields in the heap separately. The rialight::intl::ftl crate above I talked about is not used in demand, so there it probably would be possible to wrap into Arc.

Are we talking about this struct right now?

If so then most of its fields are heap-allocated anyway, regardless of whether you wrap them in an Arc or not. HashMap, HashSet, Vec, String are all heap-allocated.

I know they're heap-allocated, however it'd be nice to prevent double heap-allocating them.

Arc<Mutex<T>> is a single heap allocation now.

I don't think you can avoid two allocations for collections, like Arc<Mutex<Vec<T>>>, because the Arc has to have a stable address shared across threads for the reference count, but the collection has to be able to grow the data and reallocate its storage, which needs to change the address. These two requirements are in conflict. You'd need to do some clever stuff with virutal memory mapping to solve it, but libstd doesn't go that far.


Not much a problem in regards to collections...

Can the same be said for Arc<RwLock<f64>>?


1 Like

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.