Tcell (from qcell crate) vs Mutex

I was looking at qcell in multi threaded scenarios.

Is this better than mutex?

The question whether it’s better is not straightforward to answer. First and foremost, TCell is quite different from Mutex. A Mutex allows access to a single resource, and multiple users co-ordinare via locking. A TCell is typically one of multiple TCells that belong together and whose access will be coordinated through a corresponding TCellOwner that belongs to all the cells. For TCell in particular, a marker type is used so that only a single owner for this type can exist in the entire program, at any given time.

Typically, this owner is then stored in some central-ish location (since it’s a singleton-like object); and in case that location is shared, and you need mutable access, you might even want to employ another level of shared-mutability primitive (e.g. a Mutex) to handle access to the owner. The benefit of TCells is that

  • each individual cell doesn’t need any (space) overhead for synchronization
  • accessing many cells belonging to the same owner in rapid succession can happen with no additional synchronization overhead at all, once you got access to the owner in the first place.

The test case you link to tests the TCellOwner::wait_for_new function. Very often, you will design your program in a way that only a single TCellOwner (of a given type) is created in the first place, and use TCellOwner::new in order to create it, and panic in case your program has a bug and creates multiple owners for the same marker type. Creating a new owner is however allowed, once the previous one has been dropped, and TCellOwner::wait_for_new lets you wait for the previous owner being dropped; this is a form of locking and might remind you of a mutex, however the implementation of this function has some overhead (it works with a single global Mutex over a HashSet underneath, and all creation of all types of TCellOwner is managed through that single mutex), you won’t get good performance of you call TCellOwner::wait_for_new a lot. As its documentation explains, too, for higher performance/frequency synchronization, you should use a different strategy of putting the TCellOwner itself in a global Mutex-locked variable.


TL;DR: TCellOwner::wait_for_new can do some similar functionality to a Mutex, but it’s not indented for any performance-relative or high-frequency use-case. Using a Mutex around the owner is recommended instead in such cases.

The model of TCell is to allow access to one or more cells through a single owner; use-cases where the owner is put into a Mutex only really make any sense if you have multiple cells corresponding to a single owner, otherwise you could’ve directly used a Mutex in place of the TCell.

2 Likes