Is there a way to use atomic types in an asynchroneous context instead of an asynchronous Mutex or RwLock ?
Can standard atomics be used as is in an asynchronous context?
Or, for example, is there an asynchroneous equivalent of std::sync::atomic::AtomicUsize with load / store methods, which could replace something like tokio::sync::RwLock<usize> with read().await / write().await methods?
CodePudding user response:
Yes, using Atomics in an async context is no problem.
Most of them are lock-free (=can't even block).
Even if you would block, it is still recommended to use normal, blocking synchronization primitives over async ones, unless you hold that lock during an await.
For more info I quote the respective chapter of the tokio tutorial:
On using
std::sync::MutexNote,
std::sync::Mutexand nottokio::sync::Mutexis used to guard theHashMap. A common error is to unconditionally usetokio::sync::Mutexfrom within async code. An async mutex is a mutex that is locked across calls to.await.A synchronous mutex will block the current thread when waiting to acquire the lock. This, in turn, will block other tasks from processing. However, switching to
tokio::sync::Mutexusually does not help as the asynchronous mutex uses a synchronous mutex internally.As a rule of thumb, using a synchronous mutex from within asynchronous code is fine as long as contention remains low and the lock is not held across calls to
.await. Additionally, consider usingparking_lot::Mutexas a faster alternative tostd::sync::Mutex.
Note that this is of course only true if all the threads accessing said lock/atomic are also async worker threads. If you have external threads that could block the mutex, you have to consider waiting for that mutex a blocking operation and treat it as such.
