Exclusive (write) 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.
-
@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?
-
@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:
@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
-
@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
-
@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
@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 -
@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?
-
Take a look at QReadWriteLock
@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
-
@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
@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 :)
-
@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
@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.
-
@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)?
-
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.
-
@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
-
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...
-
@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...
@Christian-Ehrlicher said in Exclusive (write) access to a variable/data structure:
@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...
Why not if it doesn't incur significant overhead? It feels like a logical choice to me. You just lock/unlock a data object when you need without overthinking it (this is not to say you shouldn't think it over)
-
@Christian-Ehrlicher said in Exclusive (write) access to a variable/data structure:
@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...
Why not if it doesn't incur significant overhead? It feels like a logical choice to me. You just lock/unlock a data object when you need without overthinking it (this is not to say you shouldn't think it over)
This class is not meant to be derived from... use it as shown in the documentation.
-
This class is not meant to be derived from... use it as shown in the documentation.
Okay, I implemented both approaches (by inheriting QReadWriteLock and by using a local QReadWriteLock object). I didn't notice any difference – both implementations are working just fine, and block access as designed
But personally, I'm going to stick with subclassing QReadWriteLock as it feels like a lot more authentic way of doing things in C++, and you don't need to bother about helper functions (you can lock the entire data object directly) while not having to handle a separate QReadWriteLock object within the class itself