0

The doc says the QList is reentrant. So for the following code is it thread safe?

//worker thread
...
if(myList.size() == 0)
{
  ...
}

//main thread
foreach(QImage, myList)
{
 ...
}

All the ... parts have nothing to do with myList. The myList object in two threads are the same object. So is this thread safe?

Ulrich Eckhardt
  • 16,572
  • 3
  • 28
  • 55
Nyaruko
  • 4,329
  • 9
  • 54
  • 105
  • possible duplicate of [What exactly is a reentrant function?](http://stackoverflow.com/questions/2799023/what-exactly-is-a-reentrant-function) – sashoalm Apr 08 '15 at 06:31

1 Answers1

3

If myList is const and therefore all accesses are read only, this is thread safe.

But if in at least one thread code is doing non-const access on the object, this is not thread safe.

To be sure that you are doing read-only operations, declare a const reference on myList and use only this one in concurrent code :

const QList<QImage> & constMyList = myList;

This has nothing to do with reentrancy. Reentrancy tells you that if you are doing operations (read or write) on two different QList instances in two different threads respectively, the behavior is defined.

For instance, a non-reentrant class may use static functions/members in non-static methods. If these static functions/members are not guarded, the class methods will not be reentrant : even when working on two independent objects, the behavior can be undefined.

However, the Qt doc says you that read-only operations on containers is thread-safe. This is what you are looking for.

galinette
  • 8,896
  • 2
  • 36
  • 87
  • I did not explicitly declare myList as const, but the above operations are the only operations happen on myList and both of them seem read only. So the above code is thread safe? – Nyaruko Apr 07 '15 at 17:39
  • 1
    For any class in the standard library, `const` = `thread safe`. That might not be true for Qt containers, for instance they might have a `mutable` member that is not guarded by a mutex. Need a reference to exclude that. – sbabbi Apr 07 '15 at 18:12
  • I would exclude everything about `const` from the description of reentrancy. Even a `const` memberfunction may well need a mutable loop counter. Make that loop counter `static` and you have a constant but non-reentant function. Being reentrant is not required for thread-safety, but it means that you not only have to protect access to data but also access to code (because the code is bound to `static` data that must be protected). – Ulrich Eckhardt Apr 07 '15 at 20:19
  • @UlrichEckhardt : true – galinette Apr 08 '15 at 06:22
  • @sbabbi : this would be an extreme misuse of mutable... But you are right. Qt containers are thread-safe in situations where they are used read-only (from the Qt documentation) – galinette Apr 08 '15 at 06:26
  • @Nyaruko : be careful. If it is non-const, you may do non read-only operations without knowing, such as with []. Even if it may work you should always do concurrent reads on a Qt containers by using const references or const pointers, to be fool-proof. You may create a const reference on myList for this. – galinette Apr 08 '15 at 06:27
  • Just to clarify, when I wrote "mutable", I did not mean the C++ `mutable` keyword, although that is another way that access to a `const` memberfunction can require synchronization. For completeness, a third scenario is when the object who's memberfunction is `const` has a pointer/reference to a non-const object (member, parameter or global), then it can modify that object from its `const` memberfunction. – Ulrich Eckhardt Apr 08 '15 at 18:34