Exclusive (write) access to a variable/data structure
-
I have a few threads which are accessing the same data structure simultaneously, with only one changing it. However, I need to prevent other threads from reading it while it is being changed (for pretty obvious reasons). So the question is essentially about mutexes. Right now, I'm using a special flag (semaphore) in that data structure, which is raised when the data is about to be modified. But it doesn't feel like a very good solution overall, nor does it seem like a really fail-safe way of granting exclusive write access
Then what is the most elegant way of doing that (without using global variables)?
-
Take a look at QReadWriteLock
-
@deisik
Sorry, in what sense? You have said/implied you know about mutexs. Qt offers QMutex Class, you may just needlock()
&unlock()
methods. QMutexLocker Class is a convenience class for this. As with mutexs in general, both readers and writers need to know/have access the same mutex/locker instance, whether you achieve that via global variable, singleton or other approach.Shared objects need locking and unlocking around both write and read operations.
-
@JonB said in Exclusive access to a variable/data structure:
@deisik
Sorry, in what sense? You have said/implied you know about mutexs. Qt offers QMutex Class, you may just needlock()
&unlock()
methods. QMutexLocker Class is a convenience class for this. As with mutexs in general, both readers and writers need to know/have access the same mutex/locker instance, whether you achieve that via global variable, singleton or other approach.Shared objects need locking and unlocking around both write and read operations.
What are other approaches?
-
@deisik
Why do you want "other approaches"? You said yourself about needing a mutex, we respond confirming that, and you respond you now want something different. Why?If your stated goal is "Exclusive access to a variable/data structure", i.e. sharable, and across multiple threads, then what else do you have in mind? Might be different if you wanted to, e.g. send a copy via a signal, but you don't....
-
-
@JonB said in Exclusive access to a variable/data structure:
If your stated goal is "Exclusive access to a variable/data structure", i.e. sharable, and across multiple threads, then what else do you have in mind? Might be different if you wanted to, e.g. send a copy via a signal, but you don't....
Basically, I need 2 things
- No read operation can start until the write operation is over
- No write operation can start until all reads are finished
Note that I don't need to synchronize read operations as such. Multiple concurrent reads are okay and must be allowed
I use a flag which (seemingly) enables 1. For 2, I thought about implementing a counter which gets incremented on a read operation. But then I realized that this counter itself can get corrupted on concurrent writes by data read operations
@J-Hilk said in Exclusive access to a variable/data structure:
prayer
I'm already past that point
-
Take a look at QReadWriteLock
-
@deisik
One alternative could be to use signals & slots,
when a change occurs, a signal is emitted to the connected receivers.
In queue mode the signal is emitted in the receiver thread (assuming the thread has an event loop).
see here :
https://stackoverflow.com/questions/15051553/qt-signals-queuedconnection-and-directconnection -
@mpergand said in Exclusive (write) access to a variable/data structure:
@deisik
One alternative could be to use signals & slots,
when a change occurs, a signal is emitted to the connected receivers.
In queue mode the signal is emitted in the receiver thread (assuming the thread has an event loop).
see here :
https://stackoverflow.com/questions/15051553/qt-signals-queuedconnection-and-directconnectionIt would require a two-way communication, so how do you imagine it?
-
@Christian-Ehrlicher said in Exclusive (write) access to a variable/data structure:
Take a look at QReadWriteLock
That seems to be the thing
tryLockForRead() and tryLockForWrite() are the functions that I need
-
D deisik has marked this topic as solved on
-
@deisik
It's the same principle as withQMutex
s, which also have thetry...()
-type methods.https://doc.qt.io/qt-6/qreadwritelock.html#details
In many cases,
QReadWriteLock
is a direct competitor toQMutex
.QReadWriteLock
is a good choice if there are many concurrent reads and writing occurs infrequently.And, yes, as you say, don't use your own flag as accessing that will be race condition :)
-
@deisik said in Exclusive (write) access to a variable/data structure:
tryLockForRead() and tryLockForWrite() are the functions that I need
You really better should use QReadLocker and QWriteLocker for this task.
-
How much overhead does lockForRead() incur (in terms of CPU cycles)?
-
@deisik It depends on your cpu, compiler and optimization level. Why is this important? You need a locking mechanism so use one. If you have problems with the speed later on then do profiling.
-
You see, I need this feature only in very specific cases, but the data structure for which I need it is used application-wide. So if I could just inherit from QReadWriteLock for this class and make calls to its internal data tree lock-aware, it would greatly simplify things
-
@deisik said in Exclusive (write) access to a variable/data structure:
So if I could just inherit from QReadWriteLock f
Why inherit from this? There is no need for this...