Is STL empty () thread safe?

I have several threads modifying the stl vector and the stl list.
I want to avoid blocking if the container is empty.

Will the following code be thread safe? What if the items were a list or map?

class A { vector<int> items void DoStuff() { if(!items.empty()) { AquireLock(); DoStuffWithItems(); ReleaseLock(); } } } 
+7
thread-safety stl
source share
5 answers

It depends on what you expect. The other answers are correct that, as a rule, standard C ++ containers are not thread safe, and, in addition, in particular, your code does not protect another thread, changing the container between your call to empty and acquiring a lock (but this matter is not related to thread safety vector::empty ).

So, to avoid any misunderstandings: Your code does not guarantee that items will be non-empty inside the block.

But your code can still be useful, since all you want to do is to avoid redundant castle creations. Your code does not offer guarantees, but may prevent the creation of unnecessary blocking. It will not work in all cases (other threads can still remove the container between your check and the lock), but in some cases. And if everything, after which you optimize by lowering the backup lock, then your code will achieve this goal.

Just make sure that any actual access to the container is protected by locks.

By the way, above, strictly speaking, the behavior is undefined : an STL implementation is theoretically allowed to change mutable members inside an empty call. This would mean that apparently harmless (because read-only) calling empty could cause a conflict. Unfortunately, you cannot rely on the assumption that read-safe calls are safe with STL containers.

In practice, however, I am sure that vector::empty will not modify any members. But already for list::empty I'm less sure. If you really need guarantees, either block every access or do not use STL containers.

+6
source share

STL containers and algorithms have no reliable flow protection.

So, no.

+3
source share

Regardless of whether the empty thread is safe, your code will not, as it is written, fulfill your goal.

 class A { vector<int> items void DoStuff() { if(!items.empty()) { //Another thread deletes items here. AquireLock(); DoStuffWithItems(); ReleaseLock(); } } } 

The best solution is to block every time you work with items (during iteration, getting items, adding items, checking quantity / emptiness, etc.), thereby ensuring your own thread safety. So first close the lock, then check if the vector is free.

+2
source share

STL is not thread safe and empty. If you want to make a container safe, you must close all its methods using a mutex or other synchronization

+1
source share

As already mentioned, the above code is not thread safe, and locking is mandatory before doing anything with the container. But the following should have better performance than locking, and I can't think of a reason that it might be unsafe. The idea here is that locking can be expensive, and we avoid it when it is not really needed.

 class A { vector<int> items; void DoStuff() { if(!items.empty()) { AquireLock(); if(!items.empty()) { DoStuffWithItems(); } ReleaseLock(); } } } 
0
source share

All Articles