Is QList thread-safe for certain operations?
-
I know that QList is not thread-safe, and you cannot concurrently perform such operations as inserting and deleting from it, which is fairly obvious. But if I think it right, there's no possibility for race condition if you access its different indices at the same time (say, a QList of integers)
So is QList thread-safe for modifying one of its elements (with replace()) from one thread while reading its other elements (with at()) from another?
-
As long as you only use const functions from both threads everything is fine.
-
@deisik but what if you
replace()
at the same index that your other thread is reading byat()
?Modifying a list invalidates the iterators, so if you are using them in one thread while replacing an element in another thread, it can fail.
-
@sierdzio said in Is QList thread-safe for certain operations?:
@deisik but what if you
replace()
at the same index that your other thread is reading byat()
?The point is about using locks sparingly and avoiding them when they are unnecessary. So in your case specifically, a lock should kick in. In my case, on the other hand, some indices are never modified once the list has been initialized (filled), so it doesn't make sense to lock the entire list on every read of every index
Modifying a list invalidates the iterators, so if you are using them in one thread while replacing an element in another thread, it can fail
Only at() is used for iterating through the list
-
As long as you only use const functions from both threads everything is fine.
-
@Christian-Ehrlicher said in Is QList thread-safe for certain operations?:
As long as you only use const functions from both threads everything is fine.
Okay
-
D deisik has marked this topic as solved on
-
@deisik said in Is QList thread-safe for certain operations?:
So is QList thread-safe for modifying one of its elements (with replace()) from one thread while reading its other elements (with at()) from another?
This isn't entirely about thread-safety of QList anymore. If you are storing
int
s inside the QList,at()
will retrieve either the old value or the new value (assuming theint
s are properly aligned) when do areplace()
at the same time on the same index. If you store your own class in the container, your class would have to be somewhat thread-safe as well. However, I don't know an easy mechanism for locking assignment to the object (i.e. replacing its contents) against any access to the object while it is being changed. (Unless you synchronize all access to the object with a mutex.) If you store pointers to objects inside your container you get entirely different problems. Replacing a pointer is as safe as replacing an int. But, you might have a local copy of a pointer to the object which will now be replaced inside the QList. Most likely, the object will then also be destroyed by the thread that replaced the object. The local copy of the pointer is now invalid. Using shared pointers might help in this context, but they will slow down every access to the objects inside your container. (And you need to make sure that you get a copy of the shared pointer. The default implementation ofat()
will return a reference to whatever is stored inside the container, not a copy.)