Exclusive (write) access to a variable/data structure
-
wrote on 11 Oct 2023, 11:29 last edited by deisik 10 Nov 2023, 13:43
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)?
-
@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
-
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)?
-
wrote on 11 Oct 2023, 11:40 last edited by
@ollarch said in Exclusive access to a variable/data structure:
@deisik As @JonB said, use a Mutex. Lock it before accessing to data and unlock it after the access.
What mutex?
-
wrote on 11 Oct 2023, 11:43 last edited by
@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.
wrote on 11 Oct 2023, 11:44 last edited by@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?
wrote on 11 Oct 2023, 11:49 last edited by@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....
wrote on 11 Oct 2023, 13:07 last edited by deisik 10 Nov 2023, 13:35@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
wrote on 11 Oct 2023, 13:44 last edited by@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-directconnectionwrote on 11 Oct 2023, 14:16 last edited by@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
wrote on 11 Oct 2023, 14:17 last edited by deisik 10 Nov 2023, 14:30@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
-
-
@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
wrote on 11 Oct 2023, 14:34 last edited by JonB 10 Nov 2023, 14:36@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.
wrote on 11 Oct 2023, 15:47 last edited byHow 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.
wrote on 11 Oct 2023, 16:03 last edited by deisik 10 Nov 2023, 16:03You 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...
1/25